Index

Examples and Sample Code

Data Dictionary

Version

This guide is specific to the latest version of the Statseeker RESTful API, version 2.1 r16, which was made available with Statseeker version 5.6.2.

[top]

Overview

The Statseeker API (Application Programming Interface) provides access to view and edit Statseeker configuration settings, as well to retrieve and manipulate timeseries data via an interface other than that provided by the Statseeker's web GUI (Graphical User Interface). Most of the processes and objects that you are used to interacting with in Statseeker (network discovery, users, groups, devices, interfaces, device events, thresholds, reporting data, etc.) are exposed as resources from the API.

The API adheres to basic RESTful API principles:

  • Implementing resource-oriented URLs
  • Uses HTTP response codes to indicate API errors
  • Uses HTTP authentication - Basic & JSON Web Token (JWT)
  • Accepts HTTP verbs (GET, PUT, POST, and DELETE)

[top]

Code Samples

Code samples have been provided throughout this guide in a range of languages. Regardless of your implementation, in the end your request is submitted to the Statseeker API via an HTTP request, and consequently, in many instances some method of character encoding will be required. While some implementations will incorporate libraries that will handle any required encoding, others may not. In response, we have provided sample code demonstrating the use of both Unicode and URL (percent) encoding throughout this guide, so you may need to modify this aspect of the samples to suit the requirements specific to your environment.

The simplest implementation is using cURL to query the API. This allows you to begin investigating the Statseeker API with little to no requisite environmental configuration. All cURL examples provided in this guide are suited to use on a Unix based cURL implementation, which allows the use of both single quotes (') and double quotes(") for nested data objects. A Windows-based cURL implementation may not allow the use of single quotes, in this instance use double quotes and escape any inner pairs with backslash (\).

Example:
UnixWindows

curl \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    -X POST \
    "https://your.statseeker.server/api/v2.1/group/?indent=3" \
    -d '{"data":[{"name":"Group1"}]}' 

curl \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    -X POST \
    "https://your.statseeker.server/api/v2.1/group/?indent=3" \
    -d "{\"data\":[{\"name\":\"Group1\"}]}" 

Many instances of code samples in this document use nested quotes and, depending on your development environment, you may need to encode inner quote pairs so that they are interpreted correctly. In some examples we have URL encoded inner single-quotes and they are presented as %27. In other examples we have used the Unicode \u0027 for the same purpose. Presenting the samples in this way simply serves to highlight that there may be specific encoding requirements depending on your environment.

[top]

Request Headers

All requests should include the following HTTP headers:

Header Mandatory Value Notes
Accept no application/json This specifies the media type accepted in the response
Content-Type no application/json This specifies the media type of the content being sent to the API
Authorization yes Basic [base-64 encoded username:password] The Basic keyword indicates the authentication method being used and the base-64 encoded username:password pair provides the credentials needed to access the API. See Authentication for further details.
Bearer {authentication_token} The authentication token returned from a POST request to the Statseeker authentication end-point (/ss-auth)

[top]

Authentication

*** WARNING : Authentication requirements have changed with Statseeker v5.5.4 (API v2.1 r12) ***

  • v5.5.4 introduced token-based authentication, see User Authentication for details
  • New Installations: default to token-based authentication
  • Updated Servers: default to basic access authentication - this authentication method has been deprecated and will be removed in a future release

Statseeker v5.5.3 and earlier servers will only accept basic authentication.


Statseeker uses token-based authentication for user access to the server, by default, this includes API access. The Statseeker server has a resource which handles authentication requests, successful authentication returns an access token and this token must then be included with any subsequent API request. The API can also be set to use Basic Access Authentication instead of token authentication. This setting only applies to authentication with the API and does not impact user authentication via the web interface (GUI).

[top]

Set the API Authentication Method

To specify the API authentication method used:

  • Select Admin Tool > Statseeker Administration > Web Server Configuration
  • Click Edit (top-right)
  • Set RESTful API Authentication Mode as needed and click Save

See Web Server Configuration for more information.

[top]

Token-Based Authentication
  • The Statseeker server has a resource, located at https://your.statseeker.server/ss-auth, which handles authentication requests
  • To authenticate you must submit a POST request to the authentication endpoint, containing the username and password in the body of the request
  • Successful authentication will return an access token and this token must then be included with any subsequent request

The following sample code demonstrates this process:

cURLPython (requests)Ruby (rest-client)
Initial request to authenticate the user and return the authentication token.


curl \
	-D -X POST \
	-H "Content-type: application/x-www-form-urlencoded" \
	-d "user=user_name&password=user_password" \
	"https://your.statseeker.server/ss-auth"

Subsequent request to access the API.


curl \ 
	-X GET
	-H "Accept: application/json" \ 
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
	"https://your.statseeker.server/api/v2.1"


# import requests for handling connection and encoding
import requests
import json

def do_request(server, query, user, pword):

    # request auth token
    headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
    url = f'https://{server}/ss-auth'
    authData = {'user': user, 'password': pword}
    resp = requests.post(url, headers=headers, data=authData, verify=False)
    headers['Content-Type'] = 'application/json'
    url = f'https://{server}/{query}'
	
	# If auth was successful, include my token and make my API request
    if resp.status_code == 200:        
        myToken = resp.json()
        headers['Authorization'] = f'Bearer {myToken["access_token"]}'
        resp = requests.get(url, headers=headers, verify=False)
    return resp

# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'your_api_user'
pword = 'your_user_password'
# API root endpoint
query = 'api/v2.1'
# optional response formatting
query += '/?indent=3&links=none'
# Run the request
resp = do_request(server, query, user, pword)

# output the response to my API request
if resp.status_code == 200:
    print(resp.status_code)
    print(resp.json())
else:
    print(f'Error: {resp.status_code} {resp.reason}')

# install with: $ gem install rest-client
require "rest_client"
require "json"
require "base64"

def do_request(server, query, user, pword)
    # Run auth request
    headers = {
        :content_type => "application/x-www-form-urlencoded"
    }
    url = "https://" + server + "/ss-auth"
    authData = {
       :user => user,
       :password => pword
    }
    begin
        resp = RestClient::Request.execute(
            :method => :post,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
            :payload => authData
        )
   
        # Include my token and make my API request
        headers["content_type"] = :json
        url = "https://" + server + "/" + query
        rdata = JSON.parse(resp)
        headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
        return RestClient::Request.execute(
            :method => :get,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
        )
    end
end
# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'your_api_user'
pword = 'your_user_password'
# api root endpoint
$query = 'api/v2.1'
# optional formatting of the response
$query += '/?links=none&indent=3'
# Run the request
resp = do_request($server, $query, $user, $pword)
puts "#{resp.to_str}"
[top]

Example: Token-based Auth with a fall back to Basic Auth

In this example we attempt token authentication and if this process fails, we fallback to basic authentication.

PythonRuby


# import requests for handling connection and encoding
import requests
import json
def do_request(server, query, user, pword):
    # Run auth request
    headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
    url = f'https://{server}/ss-auth'
    authData = {'user': user, 'password': pword}
    resp = requests.post(url, headers=headers, data=authData, verify=False)
    headers['Content-Type'] = 'application/json'
    url = f'https://{server}/{query}'
    print(f'Get Auth Token: {resp.status_code}')
    if resp.status_code == 200:    
        # Authentication successful
        myToken = resp.json()
        headers['Authorization'] = f'Bearer {myToken["access_token"]}'
        resp = requests.get(url, headers=headers, verify=False)
    if resp.status_code == 401:
        print(f'Token auth failed: {resp.status_code}, trying basic auth')
        # Either Authentication was unsuccessful, or API set to use basic auth
        # Try basic auth
        resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
    return resp

# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'api_user'
pword = 'user_password'
# API root endpoint
query = 'api/v2.1'
# optional response formatting
query += '/?indent=3&links=none'
# Run the request
resp = do_request(server, query, user, pword)
if resp.status_code == 200:
    print(resp.status_code)
    print(resp.json())
else:
    print(f'Error: {resp.status_code} {resp.reason}')

# install with: $ gem install rest-client
require "rest_client"
require "json"
require "base64"

def try_basic(server, query, user, pword)
	headers = {
		:content_type => "json"
	}
	url = "https://" + server + "/" + query
	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
	return RestClient::Request.execute(
		:method => :get,
		:url => url,
		:headers => headers,
		:verify_ssl => false
	)
end

def do_request(server, query, user, pword)
    # Run auth request
    headers = {
        :content_type => "application/x-www-form-urlencoded"
    }
    url = "https://" + server + "/ss-auth"
    authData = {
       :user => user,
       :password => pword
    }
    begin
        resp = RestClient::Request.execute(
            :method => :post,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
            :payload => authData
        )
    rescue RestClient::Unauthorized
		# bad credentials
        try_basic(server, query, user, pword)
    else
        # Authentication successful
        headers["content_type"] = :json
        url = "https://" + server + "/" + query
        rdata = JSON.parse(resp)
        headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
        return RestClient::Request.execute(
            :method => :get,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
        )
    end
	rescue RestClient::Unauthorized
		# Statseeker may be configured for basic auth
        try_basic(server, query, user, pword)
end
# Statseeker Server IP
$server = 'your.statseeker.server'
# api user credentials
$user = 'api_user'
$pword = 'user_password'
# api root endpoint
$query = 'api/v2.1'
# optional formatting of the response
$query += '/?links=none&indent=3'
# Run the request
resp = do_request($server, $query, $user, $pword)
puts "#{resp.to_str}"
[top]

Basic Authentication (Deprecated)

The Statseeker API uses the same HTTP Basic Access (BA) authentication used by the Statseeker web interface (i.e.username:password).

This basic authentication must be included in the HTTP Authorization header for every request sent to the API, see below for examples of supplying this authorization.

cURLPython (requests)Ruby (rest-client)

curl \ 
	-H "Accept: application/json" \ 
	-H "Content-Type: application/json" \
	-u user:pword \
	"https://your.statseeker.server/api/v2.1"

 

# import requests for handling connection and encoding
import requests, json

# specify the api endpoint to be used
url = "https://your.statseeker.server/api/v2.1/"

# credentials
user = "username"
pword = "password"

# headers
headers = {"Accept":"application/json", "Content-Type":"application/json"}

# send request 
r = requests.get(url, headers=headers, auth=(user, pword))
print(r.status_code)
print(r.json())

# install with: $ gem install rest-client
require 'rest_client'

# api root endpoint
$uri = 'https:/your.statseeker.server/api/v2.1/'

# api user credentials
$user = 'username'
$pword = 'password'

# optional formatting of the response for onscreen readability
$rspFormat = '?&indent=3'

# send request
response = RestClient::Request.new({
      method: :get,
      url: $uri + $rspFormat,
      user: $user,
      password: $pword,
    }).execute
	
# output response to screen
puts "#{response.to_str}"
[top]

Manage API User's access to Data

API access also requires that the user account initiating the communication has been assigned permission to interact with the API. The default admin user account (created during the Statseeker installation process) is configured with API read/write access by default and, when creating additional Statseeker users API access can be assigned:

  • Via the web interface, by setting the API Access field, see User Accounts for details
  • Via the API, by setting api_access = rw, for read-write access (alternatively, r, or w, for read-only and write-only respectively)

Independent of a user accounts' ability to access the API is the user accounts' data access permissions. These permissions can be used to restrict the user from viewing data from specific elements of your network infrastructure. These permissions are managed through user-group associations that will have been configured when the user account was created. If you are not familiar with this process, see Users & Grouping.

You may want to consider creating a dedicated API user account:

  • Assign the account API read/write access
  • To enable access to all data, assign the account 'All Groups' permission (see Users & Grouping for details)
  • Reference this account in all API scripts

[top]

Response Codes

Statseeker uses RESTful HTTP response codes to indicate success or failure of API requests

Code Message Notes
200 Success Successful API request

Note: when referencing deprecated objects/endpoints the response will return a Status: 200 OK, but the response header will contain a Warning 299 - Deprecated API. In this instance, refer to the Resource Reference for the resource being requested.
400 Bad Request Malformed request, check request syntax and supplied parameters
401 Unauthorized Authorization error, check the supplied username and password
404 Not Found The specified endpoint cannot be located
500 Server Error Something has gone wrong on Statseeker's end


Note: if the request is correctly formed but the specified resource does not exist, then the API will return a 200 response but the data object will be an empty array.

Example Request:
We are requesting a user with an ID of not_a_valid_user_id.

https://your.statseeker.server/api/v2.1/user/not_a_valid_user_id/?links=none

Example Response:
The response will return a data object containing all the data retrieved for the specified user, in this case an empty array and the corresponding data_total is 0.


{
    "version": "2.1",
    "revision": "13",
    "info": "The Statseeker RESTful API",
    "data": {
        "success": true,
        "errmsg": "ok",
        "time": 1575850381,
        "objects": [
            {
                "type": "user",
                "sequence": 0,
                "status": {
                    "success": true,
                    "errcode": 0
                },
                "data_total": 0,
                "data": []
            }
        ]
    }
}

[top]

Limits on Size of Response Object

The API has configurable limits on the size of the data being returned from any single API query. The default value of these limits are:

  • Event based data (syslog, threshold events) is limited to 1 million rows per request
  • Timeseries data is limited to 1GB of data returned per request

These default values are intentionally set very high, and should not impact typical use of the API. They will however prevent a single API query from consuming enough system resources to severely impact the performance of your Statseeker server. The limit values can be modified to suit your Statseeker server resources, please contact Statseeker Technical Support for assistance.

[top]

Pagination

The API automatically paginates the response when large data sets are returned. By default, the API will return 50 results per response.

The number of results returned in a single response can be modified from the default value of 50 by setting the limit parameter on the request.

The following example HTTP request will return 200 results per response
https://your.statseeker.server/api/v2.1/cdt_port/?&limit=200

When moving through paginated data with the pagination links (Next, Previous, etc) the request URL is altered to append an offset request parameter. Following on from the example above, with limit=200 and setting offset=100, the request will return the 101st to 300th result:

https://your.statseeker.server/api/v2.1/cdt_port/?&limit=200&offset=100

[top]


Linked Resources

There are two types of resource links available:

Standard Links

Most resources are linked to at least one other resource in a parent-child relationship. You can use this linking to access any of the parent-resource fields from the child resource (e.g. a query to the interface object {cdt_port} can access any of the fields contained in the device resource {cdt_device} for the device that the interface resides on) This linking is one-way, from child to parent/ancestor. The format for specifying a field from a linked resource is:

{linked_resource_name}.{field}
E.g.cdt_device.name

To see which parent-resources can be linked to from a given resource, run a GET command against the describe endpoint (api/v2.1/{resource}/describe) for that resource and review content of objects.links.

Example:

api/v2.1/cdt_cpu/describe, will return something like:


{
    "version": "2.1",
    "revision": "13",
    "info": "The Statseeker RESTful API",
    "data": {
        "success": true,
        "errmsg": "ok",
        "time": 1596514086,
        "objects": [
            {
                "type": "cdt_cpu",
                "title": "CPU",
                "description": "The custom data entities for the cpu table",
                "fields": {...},
                "commands": {...},
                "info": {...},
                "allow_formula_fields": true,
                "links": {
                    "deviceLink": {
                        "title": "Link to Device",
                        "object": "cdt_device",
                        "default": 1
                    }
                },
                "global_field_options": {...}
            }
        ]
    },
    "links": [...]
}

We can see, in the response object above, that objects.links specifies a link (deviceLink) to the device resource cdt_device.

Example:

You can request data about interfaces showing a high rate of discarded packets from the cdt_port resource, and in the same call request ping-related data from the cdt_device resource of the parent device for each port.

api/v2.1/cdt_port/?fields=name,InOutDiscards,RxDiscardsPercent,TxDiscardsPercent,InOutOctets,cdt_device.name,cdt_device.ping_rtt&formats=avg&InOutDiscards_formats=total,avg&InOutOctets_formats=total&timefilter=range=now -45m to now&InOutDiscards_sort=1,desc,avg&limit=5&links=none

  • fields=name,InOutDiscards,RxDiscardsPercent,TxDiscardsPercent,InOutOctets,cdt_device.name,cdt_device.ping_rtt - the fields we want to retrieve, including name and ping from the parent object cdt_device.name,cdt_device.ping_rtt
  • formats=avg - a global formats parameter for all timeseries data
  • InOutDiscards_formats=total,avg&InOutOctets_formats=total - metric specific overrides for the formats to retrieve additional formats for some metrics
  • timefilter=range=now -45m to now - a global timefilter parameter for all timeseries data
  • InOutDiscards_sort=1,desc,avg - sort the interfaces presenting the highest discard rate to the top
  • limit=5&links=none - limit the initial response to 5 ports and don't show the links reference object

Once a field from a linked resource has been retrieved, it can be treated like any other field. You can specify formats, and timefilters for the field and you can sort and filter the response object by that field. In the example above we requested cdt_device.name, we can reference that to apply a filter to the request to only return data on the interfaces from a single device (or selection of devices).

Example:
api/v2.1/cdt_port/?fields=name,InOutDiscards,RxDiscardsPercent,TxDiscardsPercent,InOutOctets,cdt_device.name,cdt_device.ping_rtt&formats=avg&InOutDiscards_formats=total,avg&InOutOctets_formats=total&timefilter=range=now -45m to now&InOutDiscards_sort=1,desc,avg&limit=5&links=none&cdt_device.name_filter=LIKE("NewYork%25")

  • cdt_device.name_filter=LIKE("NewYork%25") - filter the response to only show ports on devices with a name starting with NewYork

Response:


{
    "info": "The Statseeker RESTful API",
    "version": "2.1",
    "data": {
        "objects": [
            {
                "status": {
                    "errcode": 0,
                    "success": true
                },
                "data": [
                    {
                        "name": "Gi6/20",
                        "cdt_device.ping_rtt": {
                            "avg": 35.5126
                        },
                        "InOutDiscards": {
                            "total": 5900.34,
                            "avg": 655.593
                        },
                        "InOutOctets": {
                            "total": 13768100000
                        },
                        "cdt_device.name": "NewYork-swt4",
                        "TxDiscardsPercent": {
                            "avg": 0.023552
                        },
                        "RxDiscardsPercent": {
                            "avg": 0
                        },
                        "id": 811
                    },
                    {
                        "name": "Gi2/28",
                        "cdt_device.ping_rtt": {
                            "avg": 47.5407
                        },
                        "InOutDiscards": {
                            "total": 5774.36,
                            "avg": 641.596
                        },
                        "InOutOctets": {
                            "total": 13159300000
                        },
                        "cdt_device.name": "NewYork-swt3",
                        "TxDiscardsPercent": {
                            "avg": 0.0231991
                        },
                        "RxDiscardsPercent": {
                            "avg": 0
                        },
                        "id": 1032
                    },
                    {
                        "name": "Gi6/18",
                        "cdt_device.ping_rtt": {
                            "avg": 35.5126
                        },
                        "InOutDiscards": {
                            "total": 5673.6,
                            "avg": 630.4
                        },
                        "InOutOctets": {
                            "total": 6980780000
                        },
                        "cdt_device.name": "NewYork-swt4",
                        "TxDiscardsPercent": {
                            "avg": 0.00432219
                        },
                        "RxDiscardsPercent": {
                            "avg": 0
                        },
                        "id": 808
                    },
                    {
                        "name": "Gi2/4",
                        "cdt_device.ping_rtt": {
                            "avg": 35.5126
                        },
                        "InOutDiscards": {
                            "total": 5418.93,
                            "avg": 602.103
                        },
                        "InOutOctets": {
                            "total": 1743290000
                        },
                        "cdt_device.name": "NewYork-swt4",
                        "TxDiscardsPercent": {
                            "avg": 0.0754798
                        },
                        "RxDiscardsPercent": {
                            "avg": 0
                        },
                        "id": 709
                    },
                    {
                        "name": "Gi7/22",
                        "cdt_device.ping_rtt": {
                            "avg": 25.2689
                        },
                        "InOutDiscards": {
                            "total": 5256.75,
                            "avg": 584.083
                        },
                        "InOutOctets": {
                            "total": 8214830000
                        },
                        "cdt_device.name": "NewYork-swt1",
                        "TxDiscardsPercent": {
                            "avg": 0
                        },
                        "RxDiscardsPercent": {
                            "avg": 0.013608
                        },
                        "id": 1491
                    }
                ],
                "type": "cdt_port",
                "data_total": 787,
                "sequence": 0
            }
        ],
        "errmsg": "ok",
        "success": true,
        "time": 1534217902
    },
    "revision": "13"
}

Resources with Multiple Links

Some resources have multiple linked resources, and some have multiple links to instances of the same resource. Take the mis_record (MAC-IP Records) resource for example. If we send a describe request to the mis_record resource, the links section of the response contains:


"links": {
	"arp_dev": {
		"title": "Link to ARP Device",
		"object": "cdt_device",
		"default": 0
	},
	"connecteddevice": {
		"title": "Link to Connected Device",
		"object": "cdt_device",
		"default": 0
	},
	"connectedport": {
		"title": "Link to Connected Interface",
		"object": "cdt_port",
		"default": 1
	},
	"deviceLink": {
		"title": "Link to Device",
		"object": "cdt_device",
		"default": 1
	},
	"port": {
		"title": "Link to Interface",
		"object": "cdt_port",
		"default": 0
	}
},

This endpoint has multiple links out to instances of the cdt_device (parent device and ARP device).

When referencing cdt_device.{field} in queries to the endpoints with multiple links to cdt_device (such as mis_record), the API will always use the link referencing the parent device. To reference another linked instance of cdt_device, such the mis_record ARP device, the link needs to be defined. This requires the following parameters:

  • {foo} - a custom named field
  • {foo}_link={name_of_link} - specify which linked resource to use
  • {foo}_object={resource_type_linked_object} - specify the resource type being linked to
  • {foo}_field={field_name} - specifying fields to be retrieved from the linked resource

Example: Requesting some fields for a specified MAC

/api/v2.1/mis_record/?fields=name,ip,vlan_name,cdt_device.name&name_filter=IS("00:00:74:db:3b:f6")

To also return the ipaddress of the ARP Router we need to add a custom named field (see Named Fields for details), and to define a link to access that ARP device to return that field. I will call my named field arpDeviceIP so my new request will be:

/api/v2.1/cdt_mis/?fields=name,ip,vlan_name,cdt_device.name,arpDeviceIP&name_filter=IS("00:00:74:db:3b:f6")&arpDeviceIP_link=arpLink&arpDeviceIP_object=cdt_device&arpDeviceIP_field=ipaddress

  • arpDeviceIP - my named field, included in the fields parameter
  • arpDeviceIP_link=arp_dev - my {foo}_link parameter, identifying which link on the mis_record record I want to retrieve data from
  • arpDeviceIP_object=cdt_device - my {foo}_object parameter, identifying the resource type I am linking to
  • arpDeviceIP_field=ipaddress - my {foo}_field parameter, identifying which field I want retrieved

Custom Links

Custom links, like their standard counter-part, allow you to query a resource and, via the defined link, request data from another resource in the same query. To achieve this the custom link is first created by linking the field from one resource to the corresponding field in another. Once the link has been created, when querying the resource defined as the 'link source' you can also query the resource defined as the 'link destination'. The syntax for specifying a field from a linked resource is the same as when using standard links:

{linked_resource_name}.{field}
E.g.cdt_device.name

Example:

We have a threshold set for an average 5-minute memory usage of over 90%. With the API we can query threshold event records for details on breaches of this threshold, but we cannot request recent memory usage data leading up to the breach because there is no link between the threshold event resource and the memory resource.

We first create a link between the threshold event and the memory resources by specifying a field that exists in both:

  • The threshold_record resource contains an entityid field which contains the ID of the entity that triggered the breach, in this instance the memory entity
  • The cdt_memory resource contains an id field which contains the ID of the memory entity

The link is created by:

  • Sending a POST command to the resource endpoint
  • Specifying the source resource and field
  • Specifying the destination resource and corresponding field

curl \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    -X POST \
    "https://my.statseeker.server/api/v2.1/link/?indent=3" \
    -d '{
          "data": [{
            "name": "memoryLink",
            "title": "Link to Memory",
            "default": 1,
            "src": "threshold_record",
            "src_fields": {"entityid": {}},
            "src_query": "{entityid}",
            "dst": "cdt_memory",
            "dst_fields": {"id": {}},
            "dst_query": "{id}"
          }]
        }'

After the link has been created, any query to the source resource can also query data from the linked destination resource. In the example above, we can request memory data while querying threshold records.

Note: for details on the link resource, refer to the link resource in the Resource Reference.

With the link created, we can now send our query containing the following URL:

https://my.statseeker.server/api/v2.1/threshold_record/?fields=time,device,entityTypeName,event,cdt_memory.memoryUsedPercent,Usage5m&Usage5m_field=memoryUsedPercent&Usage5m_object=memory&Usage5m_formats=vals&Usage5m_timefilter=range%20=%20now%20-5m%20to%20now&formats=avg,min,max&timefilter=range=start_of_today%20to%20now&entityTypeName_filter=='memory'&entityTypeName_hide=1&lastx=5&timefmt=%c

Breakdown:

  • https://your.statseeker.server/api/v2.1/threshold_record/ - the resource endpoint, specifying the threshold_record resource
  • ?fields=time,device,entityTypeName,event,cdt_memory.memoryUsedPercent,Usage5m - the fields to return, including the memoryUsedPercent field from our linked cdt_memory resource. We want to return 2 different sets of memoryUsedPercent data, so we include a custom named field, Usage5m for the second set.
Note: for details on named fields, see Named Fields.
  • &Usage5m_field=memoryUsedPercent&Usage5m_object=memory - define the custom named field as another instance of cdt_memory.memoryUsedPercent
  • &Usage5m_formats=vals&Usage5m_timefilter=range = now -5m to now - specify the format and timefilter for the custom field
  • &formats=avg,min,max&timefilter=range=start_of_today%20to%20now - specify the format and timefilter for all other timeseries metrics, in this case it is only cdt_memory.memoryUsedPercent
  • &entityTypeName_filter=='memory' - filter the returned threshold event records to just those concerning breaches of memory thresholds
  • &entityTypeName_hide=1 - we need to retrieve the entityTypeName in order to filter on it, but we don't need to see the value in my returned data, so we hide it
  • &lastx=5 - return the 5 most recent records
  • &timefmt=%c - we are specifying the format to use when displaying the time that the threshold breach occurred

Here is the response we receive from the API request:


{
    "version": "2.1",
    "revision": "13",
    "info": "The Statseeker RESTful API",
    "data": {
        "success": true,
        "errmsg": "ok",
        "time": 1596598309,
        "objects": [
            {
                "type": "threshold_record",
                "sequence": 0,
                "status": {
                    "success": true,
                    "errcode": 0
                },
                "data_total": 5,
                "data": [                    
                    {
                        "time": "Wed Aug  5 13:24:00 2020",
                        "device": "NewYork-srv4",
                        "event": "Mem905m (memory.memoryUsedPercent avg, threshold: 90%)",
                        "cdt_memory.memoryUsedPercent": {
                            "min": 5,
                            "max": 94.8153,
                            "avg": 49.3997
                        },
                        "Usage5m": {
                            "vals": [
                                89.5952,
                                92.3465,
                                93.1448,
                                94.4017,
                                94.7985
                            ]
                        },
                        "id": "5F2A2650-1B-2"
                    },
                    {
                        "time": "Wed Aug  5 13:19:00 2020",
                        "device": "Budapest-srv2",
                        "event": "Mem905m (memory.memoryUsedPercent avg, threshold: 90%)",
                        "cdt_memory.memoryUsedPercent": {
                            "min": 4.99998,
                            "max": 96.9951,
                            "avg": 50.3273
                        },
                        "Usage5m": {
                            "vals": [
                                91.668,
                                94.1118,
                                95.4288,
                                96.9171,
                                95.5872
                            ]
                        },
                        "id": "5F2A2524-16-2"
                    },
                    {
                        "time": "Wed Aug  5 13:19:00 2020",
                        "device": "NewYork-srv4",
                        "event": "Mem905m (memory.memoryUsedPercent avg, threshold: 90%)",
                        "cdt_memory.memoryUsedPercent": {
                            "min": 5,
                            "max": 94.8153,
                            "avg": 49.3997
                        },
                        "Usage5m": {
                            "vals": [
                                91.5952,
                                92.3465,
                                93.1448,
                                94.4017,
                                94.7985
                            ]
                        },
                        "id": "5F2A2524-15-2"
                    },
                    {
                        "time": "Wed Aug  5 13:14:00 2020",
                        "device": "Budapest-srv2",
                        "event": "Mem905m (memory.memoryUsedPercent avg, threshold: 90%)",
                        "cdt_memory.memoryUsedPercent": {
                            "min": 4.99998,
                            "max": 97.9951,
                            "avg": 50.3273
                        },
                        "Usage5m": {
                            "vals": [
                                91.668,
                                94.1118,
                                95.4288,
                                96.9171,
                                96.5872
                            ]
                        },
                        "id": "5F2A23F8-E-2"
                    },
                    {
                        "time": "Wed Aug  5 12:44:00 2020",
                        "device": "Pretoria-srv",
                        "event": "Mem905m (memory.memoryUsedPercent avg, threshold: 90%)",
                        "cdt_memory.memoryUsedPercent": {
                            "min": 20.1107,
                            "max": 96.9795,
                            "avg": 51.634
                        },
                        "Usage5m": {
                            "vals": [
                                91.2561,
                                91.4009,
								91.587,
                                91.8134,
                                92.0167
                            ]
                        },
                        "id": "5F2A1CF0-6C-2"
                    }                    
                ]
            }
        ]
    },
}

[top]




Named Fields

The API doesn't allow you to explicitly request the same field twice in the same call. When you want to request multiple sets of data for the same field, but with different options, you can use named fields; simply add a custom field to the fields parameter.

Example:

I want to request TxUtil data on all ports on a device but I want the data broken into today and yesterday. To do this I am going to:

  • Specify two named fields, yesterdayTx and todayTx
    fields=cdt_device.name,name,yesterdayTx,todayTx
  • Define what those fields refer to
    yesterdayTx_field=TxUtil&todayTx_field=TxUtil
  • Set specific timefilters for each named field
    yesterdayTx_timefilter=range=start_of_today -1d to start_of_today&todayTx_timefilter=range=start_of_today to now
  • Use a global formats parameter to apply to both
    formats=min,max,avg,95th
  • Filter the response to just the device in question
    cdt_device.name_filter=IS("<DEVICE NAME>")

My full request string will be:
api/v2.1/cdt_port/?fields=cdt_device.name,name,yesterdayTx,todayTx&todayTx_field=TxUtil&formats=max,min,avg,95th&todayTx_timefilter=range=start_of_today to now&yesterdayTx_field=TxUtil&yesterdayTx_timefilter=range=start_of_today -1d to start_of_today&cdt_device.name_filter=IS("<DEVICE NAME>")&links=none

The response is:


{
    "info": "The Statseeker RESTful API",
    "version": "2.1",
    "data": {
        "objects": [
            {
                "status": {
                    "errcode": 0,
                    "success": true
                },
                "data": [
                    {
                        "cdt_device.name": "<DEVICE NAME>",
                        "yesterdayTx": {
                            "max": 9.85221,
                            "avg": 9.78883,
                            "95th": 9.84576,
                            "min": 8.00007
                        },
                        "name": "Gi0/1",
                        "todayTx": {
                            "max": 9.8516,
                            "avg": 9.80882,
                            "95th": 9.84672,
                            "min": 9.34127
                        },
                        "id": 1975
                    },
                    {
                        "cdt_device.name": "<DEVICE NAME>",
                        "yesterdayTx": {
                            "max": 786.667,
                            "avg": 294.361,
                            "95th": 766.18,
                            "min": 83.6935
                        },
                        "name": "Gi0/2",
                        "todayTx": {
                            "max": 543.072,
                            "avg": 182.109,
                            "95th": 497.423,
                            "min": 95.8462
                        },
                        "id": 1976
                    },
                    {
                        "cdt_device.name": "<DEVICE NAME>",
                        "yesterdayTx": {
                            "max": 783.816,
                            "avg": 256.446,
                            "95th": 714.649,
                            "min": 94.7673
                        },
                        "name": "Gi0/3",
                        "todayTx": {
                            "max": 786.667,
                            "avg": 495.852,
                            "95th": 781.882,
                            "min": 96.1355
                        },
                        "id": 1977
                    },
                    {
                        "cdt_device.name": "<DEVICE NAME>",
                        "yesterdayTx": {
                            "max": 7.48404,
                            "avg": 3.68874,
                            "95th": 4.88369,
                            "min": 0.995533
                        },
                        "name": "Gi0/4",
                        "todayTx": {
                            "max": 7.70181,
                            "avg": 4.54324,
                            "95th": 5.55599,
                            "min": 2.71828
                        },
                        "id": 1978
                    },
                    {
                        "cdt_device.name": "<DEVICE NAME>",
                        "yesterdayTx": {
                            "max": 8.37714,
                            "avg": 2.99202,
                            "95th": 6.29977,
                            "min": 0.96669
                        },
                        "name": "Gi0/5",
                        "todayTx": {
                            "max": 8.24358,
                            "avg": 6.07991,
                            "95th": 7.4297,
                            "min": 3.94083
                        },
                        "id": 1979
                    }
                ],
                "type": "cdt_port",
                "data_total": 5,
                "sequence": 0
            }
        ],
        "errmsg": "ok",
        "success": true,
        "time": 1533779107
    },
    "revision": "13"
}

Named fields are also required when:

  • A resource has multiple links to the same resource type - one of these will be the default link and the others not
  • You want to refence a non-default linked resource

A named field is defined for each field you want returned from a non-default linked resource, see Multiple Links to the same resource for details.

[top]




Field Formulas

Field formulas allow you to request a user defined/named field (for more information see named fields) and populate that field via a formula based on other fields returned in the request. The formula accepts SQL operators and conventions, and can reference the values of other fields returned by the query. To define the formula:

  • The named field must be specified in the fields parameter
  • Use the following parameters to define the formula used to populate the field:
    • <MY NAMED FIELD>_formula - use when the query does not aggregate data or when the query aggregates data and the formula should be applied prior to aggregation
    • <MY NAMED FIELD>_post_formula - use when the query aggregates data and the formula should be applied after aggregation has occurred

Both pre and post-aggregation formula can be applied in a single query, but a single named field cannot utilize both pre and post-aggregation formulas. In this instance specify two named fields, one for pre-aggregation formula and the other for post-aggregation formula.

When referencing other fields in your formula use the following syntax:

  • Configuration field: {field}, e.g. {ping_poll}
  • Timeseries/Event fields must also define a data format: {field:format}, e.g. {ping_rtt:current}
  • Every field specified in the formula must also be specified in the fields parameter
  • Every data format applied to a field referenced in a formula must also be specified for that field elsewhere in the query, either in the global formats parameter, or the field specific <FIELD>_formats parameter

[top]


Formula Example: Convert InOctets to Mebibytes

Request: /api/v2.1/cdt_port/?fields=cdt_device.name,name,InOctets,InMB&timefilter=range = now -30m to now&formats=vals&InMB_formula={InOctets:vals}/1024/1024&cdt_device.name_filter=IS("<DEVICE NAME>")

The request:

  • Defines a named field, InMB
  • Specifies the formula to use to populate that field: InMB_formula={InOctets:vals} / 1024 / 1024
  • Must include any field referenced within the formula as well as any required data format, in this case {InOctets:vals}

Response:


{
    "version": "2.1",
    "revision": "13",
    "info": "The Statseeker RESTful API",
    "data": {
        "success": true,
        "errmsg": "ok",
        "time": 1597795111,
        "objects": [
            {
                "type": "cdt_port",
                "sequence": 0,
                "status": {
                    "success": true,
                    "errcode": 0
                },
                "data_total": 2,
                "data": [
                    {
                        "cdt_device.name": "<DEVICE NAME>",
                        "name": "int.2",
                        "InOctets": {
                            "vals": [
                                72506880,
                                72525312,
                                72607744,
                                72499968,
                               ...
                                73761536,
                                72515328
                            ]
                        },
                        "InMB": [
                            69.1479,
                            69.1655,
                            69.2441,
                            69.1414,
                            ...
                            70.3445,
                            69.156
                        ],
                        "id": 591
                    },
                    {
                        "cdt_device.name": "<DEVICE NAME>",
                        "name": "int.3",
                        "InOctets": {
                            "vals": [
                                1204222976,
                                1162312704,
                                1141559296,
                                1186676992,
                                ...
                                1385965824,
                                1365224192
                            ]
                        },
                        "InMB": [
                            1148.44,
                            1108.47,
                            1088.68,
                            1131.7,
                            ...
                            1321.76,
                            1301.98
                        ],
                        "id": 592
                    }
                ]
            }
        ]
    },
    "links": []
}

[top]




Formula Example: Ping Latency Gauge using a Case Statement

Request: /api/v2.1/cdt_device/?fields=name,ping_rtt,status&timefilter=range = now -30m to now&formats=avg&status_formula=CASE WHEN {ping_rtt:avg} < 10 THEN 'Green' WHEN {ping_rtt:avg} < 50 THEN 'Amber' WHEN {ping_rtt:avg} IS NULL THEN 'Unknown' ELSE 'Red' END

The request:

  • Defines a named field, status
  • Provides a case statement to populate that field: status_formula=CASE WHEN {ping_rtt:avg} < 10 THEN 'Green' WHEN {ping_rtt:avg} < 50 THEN 'Amber' WHEN {ping_rtt:avg} IS NULL THEN 'Unknown' ELSE 'Red' END
  • Must include any field referenced within the formula as well as any required data format, in this case {ping_rtt:avg}

Response:


{
    "version": "2.1",
    "revision": "13",
    "info": "The Statseeker RESTful API",
    "data": {
        "success": true,
        "errmsg": "ok",
        "time": 1597793987,
        "objects": [
            {
                "type": "cdt_device",
                "sequence": 360,
                "status": {
                    "success": true,
                    "errcode": 0
                },
                "data_total": 226,
                "data": [
                    {
                        "name": "NewYork-ups1",
                        "ping_rtt": {
                            "avg": 35.4
                        },
                        "status": "Amber",
                        "id": 338
                    },
                    {
                        "name": "NewYork-ups2",
                        "ping_rtt": {
                            "avg": 41.7333
                        },
                        "status": "Amber",
                        "id": 339
                    },
                    {
                        "name": "NewYork-swt2",
                        "ping_rtt": {
                            "avg": 52.6
                        },
                        "status": "Red",
                        "id": 347
                    },
					
                    ...
					...
					
					
                    {

                        "name": "Phoenix-swt1",
                        "ping_rtt": {
                            "avg": 41.6667
                        },
                        "status": "Amber",
                        "id": 387
                    }
                ]
            }
        ]
    },
    "links": []
}

[top]




Formula Example: Nested Formulas

Request: /api/v2.1/cdt_device/?fields=name,sysLocation,ping_rtt,status,prettyPing,prettyStatus&timefilter=range = now -30m to now&formats=avg&status_formula=CASE WHEN {ping_rtt:avg} < 10 THEN 'Green' WHEN {ping_rtt:avg} < 50 THEN 'Amber' WHEN {ping_rtt:avg} IS NULL THEN 'Unknown' ELSE 'Red' END&prettyPing_formula={ping_rtt:avg} || ' ms'&prettyStatus_formula={status} || ' (' || {prettyPing} || ')'&sysLocation_filter=IS("LosAngeles")

The request:

  • Defines a multiple named fields: status, prettyPing, prettyStatus
  • Defines formula to populate each:
    • status_formula=CASE WHEN {ping_rtt:avg} < 10 THEN 'Green' WHEN {ping_rtt:avg} < 50 THEN 'Amber' WHEN {ping_rtt:avg} IS NULL THEN 'Unknown' ELSE 'Red' END
    • prettyPing_formula={ping_rtt:avg} || ' ms'
    • prettyStatus_formula={status} || ' (' || {prettyPing} || ')' - requires output from other formula fields
  • Must include any field referenced within the formula as well as any required data format, in this case {ping_rtt:avg}, {status} and {prettyPing}

Response:


{
    "version": "2.1",
    "revision": "13",
    "info": "The Statseeker RESTful API",
    "data": {
        "success": true,
        "errmsg": "ok",
        "time": 1597796468,
        "objects": [
            {
                "type": "cdt_device",
                "sequence": 360,
                "status": {
                    "success": true,
                    "errcode": 0
                },
                "data_total": 12,
                "data": [
                    {
                        "name": "LosAngeles-ups1",
                        "sysLocation": "LosAngeles",
                        "ping_rtt": {
                            "avg": 38.1333
                        },
                        "status": "Amber",
                        "prettyPing": "38.1333 ms",
                        "prettyStatus": "Amber (38.1333 ms)",
                        "id": 350
                    },
                    {
                        "name": "LosAngeles-ups2",
                        "sysLocation": "LosAngeles",
                        "ping_rtt": {
                            "avg": 32.4
                        },
                        "status": "Amber",
                        "prettyPing": "32.4 ms",
                        "prettyStatus": "Amber (32.4 ms)",
                        "id": 351
                    },
					...
					...
                    {
                        "name": "LosAngeles-rtr",
                        "sysLocation": "LosAngeles",
                        "ping_rtt": {
                            "avg": 43.8
                        },
                        "status": "Amber",
                        "prettyPing": "43.8 ms",
                        "prettyStatus": "Amber (43.8 ms)",
                        "id": 361
                    }
                ]
            }
        ]
    },
    "links": []
}

[top]

API Endpoints

The API allows you to add, retrieve and modify data relating to a large number of data-object/resource types. These resources are related to either the network hardware that your Statseeker server is monitoring, or various configuration settings (user accounts, thresholds and alerts, automated processes, network configuration details, etc.) applied to your Statseeker server.

Most API's feature a static selection of object-focused endpoints, which are available to everyone. The Statseeker API is a little different, while many resources are available through the default installation, some are available as modular Custom Data Type (CDT) packages which can be added and removed as needed. This feature, combined with the fact that Statseeker doesn't force users to upgrade their installation, means that the resource-level endpoints available on one Statseeker deployment may be quite different to those available on another.

Note:

The remainder of this section provides a basic overview of the types of endpoints available through the API, and the types of requests that can be made against those endpoint types. These endpoint types, and their available actions, are universal across deployments, but the data objects available at the resource level may differ between Statseeker installations.

Endpoint URL Description
Statseeker Endpoints
Authentication /ss-auth

https://your.statseeker.server/ss-auth

The authentication endpoint authenticates users and generates authentication tokens
API Endpoints
API Root /api/{api_version}/

https://your.statseeker.server/api/v2.1/

The root endpoint for the API
Resource /api/{api_version}/{resource}

https://your.statseeker.server/api/v2.1/user

The resource endpoint, for running get, add, update, and delete queries on specific resources. This is the endpoint type used to retrieve your timeseries and configuration data from your Statseeker server, see:

  • Resource Endpoint for details on the parameters that can be passed when interacting with resource level endpoints
  • Resource Reference for details on the various resource level endpoints including fields, methods and requirements
Describe /api/{api_version}/{resource}/describe

https://your.statseeker.server/api/v2.1/user/describe

The describe endpoint, for running describe queries on specific resources
Execute /api/{api_version}/{resource}/execute

https://your.statseeker.server/api/v2.1/discover/execute

The execute endpoint, for running execute queries on specific resources
ID /api/{api_version}/{resource}/{id}

https://your.statseeker.server/api/v2.1/user/1234

The ID endpoint, for running get, update, and delete queries on a specific entry within a resource
Field /api/{api_version}/{resource}/{id}/{field}

https://your.statseeker.server/api/v2.1/user/1234/name

The field endpoint, for running update queries on a field of a specific entry within a resource

[top]

Authentication Endpoint (/ss-auth))

This endpoint is used to authenticate users and generate authentication tokens for use in API requests. For details on this endpoint and examples of authenticating users see Authentication.

[top]

Root Endpoint (/api/v2.1)

The base (root) endpoint for the API is:

  • https://your.statseeker.server/api/[api_version]

, where:

  • https://your.statseeker.server is the URL of your Statseeker server
  • [api_version] is one the accepted version references, see below
Version References Message
v1 Version 1 of the API, this is a legacy, read-only api, and is not covered in this document
v2, v2.0 Version 2 of the API, the initial implementation of the Statseeker RESTful Read-Write API
v2.1 Version 2.1 of the API, added access to all timeseries data (device\interface metrics) collected by Statseeker
latest Currently, Version 2.1 of the API

[top]

Versioning

The base endpoint of /api/latest will return the latest version of the API installed on your Statseeker server. This version is identified in every response from the API in the version key.

Example Response:


{
    "info": "The Statseeker RESTful API",
    "version": "2.1",
    "data": {response_data},
    "revision": "13"
}

You can access an API version, other than the latest, by altering your base URL to specify the version you want to use.

E.g./api/v1 will return API v1, or /api/v2 will return API v2.0.

There may be multiple revisions released for a given API version, these revisions address issues relating to bugs within the API itself, and issues relating to Custom Data Type (CDT) packages that the API can interact with.

For more information on the relationship between the API and CDT packages, see API Endpoints.

[top]

GET

A GET request to the root endpoint will return all resource types available to your Statseeker installation.

The parameters that may be passed when sending a GET request.

Parameters Type/Valid Values Description
links
  • only - only return the links object, no data object
  • none - only return the data object, no links object
  • html - return html links. If the response is being displayed in a browser then the links may be clicked to send a GET request for the associated object/field.
  • htmlonly - only return html links, no data object
Modifies how the links contained within the response object are presented
indent positive integer Number of characters to indent when formatting code blocks for display

[top]

Resource Endpoint (/api/v2.1/{resource})

The resource level endpoints are where you will spend the vast majority if your time when interacting with the Statseeker API. In order to retrieve reporting data on your network infrastructure you will be routinely sending GET requests to resource level endpoints. These requests will contain:

  • The resource level endpoint to specify what type of data objects you are reporting on (device, interface, CPU, memory, etc.)
  • filters to specify which of these data objects to return
  • fields and formats parameters to specify what data is to be returned (average outbound traffic, maximum aggregated CPU load, etc.)
  • timefilters to specify the reporting period

The Statseeker RESTful API contains many resources allowing you to access and interact with both the data that Statseeker has collected on your network, and the configuration options used by Statseeker to collect and manage that data. Some of the object types available at the resource level endpoint include:

  • Users (/api/v2.1/user)
  • Groups (/api/v2.1/group)
  • Devices (/api/v2.1/cdt_device)
  • Interfaces (/api/v2.1/cdt_port)

As of Statseeker v5.6.2, the API contained 332 resource level endpoints, all aspects of these endpoints are detailed in the Resource Reference. This list can be expanded upon by adding CDT packages and additional modules for new data types. For a complete list of all resources available, from your Statseeker installation:

  • Send a GET request to the root endpoint, this will return a list of all available resource level endpoints
  • Refer to the Resource Reference for details on each of those resources

[top]

Get

Send a GET request to a resource endpoint to return details on instances of the specified resource.

The parameters that may be passed when sending a GET request.

Parameters Type/Valid Values Description
fields A comma separated list of field names
E.g.fields=id,name,location
The list of fields that will be returned in the response. This parameter will be ignored if fields_adv is also specified.
fields_adv A JSON string detailing the fields to be returned
E.g.fields_adv={"Device Name":{"field":"name"}, "IP":{"field":"ipaddress"},"Location":{"field":"sysLocation"},"SNMP Polling":{"field":"snmp_poll","filter":{"query":"=%27off%27"}}}
The list of fields that will be returned in the response
filter An SQL filter string
E.g."SNMP Polling":{"field":"snmp_poll","filter":{"query":"=%27off%27"}}
A filter to be applied to the response data inside of fields_adv
groups A comma separated list of group names or group IDs A list of groups to be used to filter the response data, only data associated with members of the specified groups will be returned
grouping_mode
  • AND
  • OR
The mode to use when processing multiple group parameters
group_by
  • A comma separated array of fields names, or a formula that will be applied to field values
    • Each field name must be enclosed in braces {}
    • The data format must be specified for every timeseries or event field


    Examples:

    • array, 1 value: group_by={name} - aggregate data by entity name, if the request was made to cdt_device, then data would be aggregated by device name
    • array, multiple values: group_by={cdt_device.name},{ifSpeed} - aggregate interface data by device name, and then by interface speed within interfaces on that device
    • array, multiple values and formula: group_by={cdt_device.name},{TxUtil:median} < 50 - aggregate interface data by device name, and then (for each device) by the whether or not the median TxUtil is less than 50

OR

  • Aggregate the results by the Statseeker group/s the specified entity is found in. Each API object lists its entityid_fields in the info block in the description. The API will use the value in these fields as the entityid. If an object lists multiple entityid_fields, then all of them are used (ie. if any of the values are in a group, the row will be considered in that group). One of:
    • ~group~ - returns the group name, requires that ~group~ be listed in the fields parameter
    • ~groupid~ - returns the group id, requires that ~groupid~ be listed in the fields parameter
    • ~group~:<FIELD> - use the specified field as the 'entityid' field rather than the field/s listed in the entityid_fields. Requires that ~group~ be listed in the fields parameter and that the nominated field is specified in the API request (fields parameter, formula fields or linked fields).


    Examples:

    • group_by={~group~} - aggregate data by group, return the group name as a row identifier
    • group_by={~groupid~} - aggregate data by group, return the group ID as a row identifier
    • group_by={~group~:deviceid}- aggregate data by group, use the associated deviceid as an entity identifier, return the group name as a row identifier

For examples of using group_by, see Using 'group_by' for Data Aggregation.

Use when you want to aggregate data across multiple entities, such as total traffic across multiple interfaces.

Requires that:

  • Field names be enclosed in braces {}
  • The fields to be grouped by are specified in the fields parameter of the request
  • The field format be provided for any timeseries/event fields specified in the group_by parameter
    • When using an array, the {field}_aggregation_format parameter is used to specify the format to be applied
    • When using a formula, the format is appended to the field name, separated by a colon (:)

When grouping by groups, an extra group with the name/ID None/null may be returned, containing any rows that weren't in any of the groups.

interval positive integer
E.g.interval=300
The polling interval to be applied to all timeseries metrics specified in the fields parameter. When not specified, the default polling interval of 60 seconds is used.
limit positive integer
E.g.limit=100
The number of items to return per 'page' of the response, see Pagination for details. The API will automatically paginate response data with a default limit=50.
offset positive integer
E.g.offset=100
The number of result items to skip, see Pagination for details. The API will automatically paginate response data with a default offset={limit}.
precision positive integer
E.g. precision=5
The number of decimal places to return for all timeseries metrics specified in the fields parameter.
The default precision value varies between fields, supply this parameter when you want to enforce a specific level of precision across all timeseries fields.
sortmode string

  • novals_after - null values are always sorted after valid values, only valid values are affected by the {field}_sort parameter
  • novals_before - null values are always sorted before valid values, only valid values are affected by the {field}_sort parameter
  • novals_large - null values are counted as larger than any other value and will be sorted to the end of results if the field is sorted ascending, and sorted to the start if sorted descending
  • novals_small - null values are counted as smaller than any other value and will be sorted to the start of results if a field is sorted ascending, and sorted to end if sorted descending
Specify how the response should handle null values.
Default =novals_small, this setting is used in all instances where sortmode is not set.

timefmt string
The syntax for specifying the time format matches that used by STRFTIME.

E.g. timefmt=%A %H:%M:%S (%y-%m-%d)
will return a timestamp in the format
Wednesday 15:44:48 (19-07-17)
The format in which to return timestamps when value_time is set
value_time One of:

  • start - The timestamp at which the event began
  • mid - the midpoint of the start and end timestamps
  • end - the timestamp at which the event finished
  • all - an array of start, mid and end
  • none - do not return a timestamp

E.g.value_time=all

Optionally return a timestamp for returned timeseries data points. Timestamps are return in epoch time unless timefmt is also specified.


When the fields parameter has been specified, the following additional parameters may be used.

Parameters Type/Valid Values Description
{field}_field string A user defined variable name followed by a valid field name for the resource.

E.g.yesterday_RxUtil

See Named Fields for more information and examples.
{field}_formats Comma separated list, see Timeseries Data: Stats, Formats & Options The formats to request from the API for the given field, required for timeseries data fields

Note: a global formats key (formats=) may also be used to apply the same values to all timeseries metrics specified in fields
{field}_formula string Specify an SQL-style formula to be used to populate the field, see Field Formulas for details.

Syntax for referencing other fields within the formula:

  • Configuration field: {field}, e.g. {ping_poll}
  • Timeseries/Event fields must also define a data format: {field:format}, e.g. {ping_rtt:current}
{field}_filter string The filter to apply to the given field. These filters can be either SQL-style filters or extended RegEx filters, for details and examples of applying filters see:

{field}_filter_format string The format to use for the filter, required for timeseries data fields
{field}_interval integer The polling interval (in seconds) to use for the specified field. When used, a field-specific timefilter for the specified field must also be used.

Note: when not specified, the default interval of 60 seconds is used. A global interval key (interval=) may also be used to apply the same values to all timeseries metrics specified in fields
{field}_link string Required when:

  • A resource has multiple links to the same resource type - one of these will be the default link and the others not
  • You want to refence a non-default linked resource

See Multiple Links to the same resource for details.

{field}_object string Required when:

  • A resource has multiple links to the same resource type - one of these will be the default link and the others not
  • You want to refence a non-default linked resource

See Multiple Links to the same resource for details.

{field}_post_filter string The filter to apply to the given field after data aggregation has occurred. This parameter works exactly the same as {field}_filter, except the filter is applied after data aggregation.
{field}_post_formula string The formula to apply to the given field after data aggregation has occurred. This parameter works exactly the same as {field}_formula, except the formula is applied after data aggregation.
{field}_precision positive integer
E.g. {field}_precision=5
The number of decimal places to return for the specified timeseries metric.
The default precision value varies between fields, supply this parameter when you want to enforce a specific level of precision.

Note: a global precision key (precision=) may also be used to apply the same value to all timeseries metrics specified in fields
{field}_timefilter string The timefilter to use for the given field, required for timeseries data fields.

Note: a global timefilter key (timefilter=) may also be used to apply the same values to all timeseries metrics specified in fields
{field}_tz string An alternate timezone to use for the {field}_timefilter.

All timefilters use the Statseeker server's timezone unless an override is specified by supplying {field}_tz.

Note: a global timezone key (tz=) may also be used to apply the same values to all timeseries metrics specified in fields
{field}_sort Comma separated list List specifying the sort hierarchy and direction, in the following format:{field}_sort={rank}{direction} and for Timeseries data:{field}_sort={rank}{direction}{format}
E.g.name_sort=1,asc
RxUtil_sort=1,desc,avg
{field}_stats Comma separated list, see Timeseries Data: Stats, Formats & Options The stats to use for the given field
{field}_aggregation_format One of:

Format Description
95th The 95th percentile of the values
avg The average of the values
cat Concatenation of the values. Not supported for non-scalar formats such as vals
count The number of rows that match, and have a non-null value
count_all The number of rows that match, including NULL values
first The first matching value
last The last matching value
list Concatenate values as per the cat format, but return the output as comma separated list of values
max The maximum value
median The median value
min The minimum value
stddev The standard deviation value
sum The sum of all values
total Similar to sum, but returns 0 instead of NULL if there are only NULL values in the data being aggregated
The aggregation format to use for the specified field

Note: using aggregation, the following rules apply:

  • When the aggregated data is a number - ignore all null values and return the aggregated value required based on non-null values only
  • When the aggregated data is NOT a number - attempt to convert all values to a number prior to aggregation. Any instance of null will result in the aggregated value being returned as null.

[top]


GET Example: Retrieving Details on Multiple Devices

Return specified details on all devices in a specified group, the fields I am returning are:

  • name
  • id
  • community
  • ipaddress
  • snmp_version
cURLPythonRubyResponse

curl \
	-H "Accept: application/json" \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
	-X GET \
	"https://your.statseeker.server/api/v2.1/cdt_device/?fields=name,id,community,ipaddress,snmp_version&groups=<GROUP NAME>&indent=3"


# import requests for handling connection and encoding
import requests
import json
def do_request(server, query, user, pword):
    # Run auth request
    headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
    url = f'https://{server}/ss-auth'
    authData = {'user': user, 'password': pword}
    resp = requests.post(url, headers=headers, data=authData, verify=False)
    headers['Content-Type'] = 'application/json'
    url = f'https://{server}/{query}'
    print(f'Get Auth Token: {resp.status_code}')
    if resp.status_code == 200:    
        # Authentication successful
        myToken = resp.json()
        headers['Authorization'] = f'Bearer {myToken["access_token"]}'
        resp = requests.get(url, headers=headers, verify=False)
    if resp.status_code == 401:
        print(f'Token auth failed: {resp.status_code}, trying basic auth')
        # Either Authentication was unsuccessful, or API set to use basic auth
        # Try basic auth
        resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
    return resp

# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'api_user'
pword = 'user_password'
# API root endpoint
query = 'api/v2.1'
# specify target endpoint
query += '/cdt_device'
# specify fields to be returned
query += '/?fields=name,id,community,ipaddress,snmp_version'
# Filters
query += '&groups=<GROUP NAME>'
# optional response formatting
query += '&indent=3&links=none'
# Run the request
resp = do_request(server, query, user, pword)
if resp.status_code == 200:
    print(resp.status_code)
    print(resp.json())
else:
    print(f'Error: {resp.status_code} {resp.reason}')


# install with: $ gem install rest-client
require "rest_client"
require "json"
require "base64"

def try_basic(server, query, user, pword)
	headers = {
		:content_type => "json"
	}
	url = "https://" + server + "/" + query
	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
	return RestClient::Request.execute(
		:method => :get,
		:url => url,
		:headers => headers,
		:verify_ssl => false
	)
end

def do_request(server, query, user, pword)
    # Run auth request
    headers = {
        :content_type => "application/x-www-form-urlencoded"
    }
    url = "https://" + server + "/ss-auth"
    authData = {
       :user => user,
       :password => pword
    }
    begin
        resp = RestClient::Request.execute(
            :method => :post,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
            :payload => authData
        )
    rescue RestClient::Unauthorized
		# bad credentials
        try_basic(server, query, user, pword)
    else
        # Authentication successful
        headers = {
			:content_type => "application/json"
		}	
        url = "https://" + server + "/" + query
        rdata = JSON.parse(resp)
        headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
        return RestClient::Request.execute(
            :method => :get,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
        )
    end
	rescue RestClient::Unauthorized
		# Statseeker may be configured for basic auth
        try_basic(server, query, user, pword)
end
# Statseeker Server IP
$server = 'your.statseeker.server'
# api user credentials
$user = 'api_user'
$pword = 'user_password'
# api root endpoint
$query = 'api/v2.1'
# specify target endpoint
$query += "/cdt_device"
# specify fields to be returned
$query += '?fields=name,id,community,ipaddress,snmp_version'
# Filters
$query += '&groups=<GROUP NAME>'
# optional response formatting
$query += '&indent=3&links=none'
# Run the request
resp = do_request($server, $query, $user, $pword)
puts "#{resp.to_str}"


{
  "info": "The Statseeker RESTful API",
  "data": {
    "objects": [
      {
        "status": {
          "errcode": 0,
          "success": true
        },
        "data": [
          {
            "snmp_version": 2,
            "ipaddress": "10.116.4.172",
            "name": "Brisbane-Server1",
            "community": "public",
            "id": 551
          },
          {
            "snmp_version": 2,
            "ipaddress": "10.116.4.180",
            "name": "Brisbane-Server2",
            "community": "public",
            "id": 552
          },
          {
            "snmp_version": 2,
            "ipaddress": "10.116.4.186",
            "name": "Sydney-Server1",
            "community": "public",
            "id": 555
          },
          {
            "snmp_version": 2,
            "ipaddress": "10.116.4.187",
            "name": "Sydney-Server2",
            "community": "public",
            "id": 556
          },
          {
            "snmp_version": 2,
            "ipaddress": "10.116.4.194",
            "name": "Melbourne-Server1",
            "community": "public",
            "id": 557
          }
        ],
        "type": "cdt_device",
        "data_total": 5
      }
    ],
    "errmsg": "ok",
    "success": true,
    "time": 1496188135
  },
  "links": [],
  "api_version": "2.1"
}
[top]

POST

Use the POST request to create new instances of the specified resource. The data object included in a POST request must be a json string with a single data key. Some resource types will require additional keys within the data object, use the /describe endpoint to view the requirements for a given resource.

[top]

Example: Creating Multiple Groups

RequestPythonRubyResponse

curl \
	-H "Accept: application/json" \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
	-X POST \
	"https://your.statseeker.server/api/v2.1/group/?indent=3" \
	-d '{"data":[{"name":"<GROUP NAME 1>"},{"name":"<GROUP NAME 2>"}]}' 



# import requests for handling connection and encoding
import requests
import json
def do_request(server, query, user, pword, reqData):
    # Run auth request
    headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
    url = f'https://{server}/ss-auth'
    authData = {'user': user, 'password': pword}
    resp = requests.post(url, headers=headers, data=authData, verify=False)
    headers['Content-Type'] = 'application/json'
    url = f'https://{server}/{query}'
    print(f'Get Auth Token: {resp.status_code}')
    if resp.status_code == 200:    
        # Authentication successful
        myToken = resp.json()
        headers['Authorization'] = f'Bearer {myToken["access_token"]}'
        resp = requests.post(url, headers=headers, data=reqData, verify=False)
    if resp.status_code == 401:
        print(f'Token auth failed: {resp.status_code}, trying basic auth')
        # Either Authentication was unsuccessful, or API set to use basic auth
        # Try basic auth
        resp = requests.post(url, headers=headers, auth=(user, pword), data=reqData, verify=False)
    return resp

# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'api_user'
pword = 'user_password'
# API root endpoint
query = 'api/v2.1'
# specify target endpoint
query += '/group'
# optional response formatting
query += '/?indent=3&links=none'
# data
reqData = json.dumps({"data":[{"name":"<GROUP NAME 1>"},{"name":"<GROUP NAME 2>"}]})
# Run the request
resp = do_request(server, query, user, pword, reqData)
if resp.status_code == 200:
    print(resp.status_code)
    print(resp.json())
else:
    print(f'Error: {resp.status_code} {resp.reason}')


# install with: $ gem install rest-client
require "rest_client"
require "json"
require "base64"

def try_basic(server, query, user, pword, reqData)
	headers = {
		:content_type => "application/json"
	}
	url = "https://" + server + "/" + query
	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
	return RestClient::Request.execute(
		:method => :post,
		:url => url,
		:headers => headers,
		:verify_ssl => false,
		:payload => reqData
	)
end

def do_request(server, query, user, pword, reqData)
    # Run auth request
    headers = {
        :content_type => "application/x-www-form-urlencoded"
    }
    url = "https://" + server + "/ss-auth"
    authData = {
       :user => user,
       :password => pword
    }
    begin
        resp = RestClient::Request.execute(
            :method => :post,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
            :payload => authData
        )
    rescue RestClient::Unauthorized
		# bad credentials
        try_basic(server, query, user, pword, reqData)
    else		
        # Authentication successful
		headers = {
			:content_type => "application/json"
		}	
        url = "https://" + server + "/" + query
        rdata = JSON.parse(resp)
        headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
        return RestClient::Request.execute(
			:method => :post,
			:url => url,
			:headers => headers,
			:verify_ssl => false,
			:payload => reqData
        )
    end
	rescue RestClient::Unauthorized
		# Statseeker may be configured for basic auth
        try_basic(server, query, user, pword, reqData)
end
# Statseeker Server IP
$server = 'your.statseeker.server'
# api user credentials
$user = 'api_user'
$pword = 'user_password'
# api root endpoint
$query = 'api/v2.1'
# specify target endpoint
$query += '/group'
# optional response formatting
$query += '/?indent=3&links=none'
# configure payload
$reqData = '{"data":[{"name":"<GROUP NAME 1>"},{"name":"<GROUP NAME 2>"}]}'
# Run the request
resp = do_request($server, $query, $user, $pword, $reqData)
puts "#{resp.to_str}"

{
  "info": "The Statseeker RESTful API",
  "data": {
    "objects": [
      {
        "status": {
          "errcode": 0,
          "success": true
        },
        "data": [
          {
            "name": "<GROUP NAME 1>",
            "id": 46458
          },
          {
            "name": "<GROUP NAME 2>",
            "id": 46459
          }
        ],
        "type": "group",
        "data_total": 2
      }
    ],
    "errmsg": "ok",
    "success": true,
    "time": 1496190459
  },
  "api_version": "2.1"
}
[top]

PUT Requests

Use the PUT request to update an existing instance of the specified resource. The data object included must be a json string with both a fields key (to identify the resource/s to be updated) and a data key (to specify the data to be updated). Some resource types will require additional keys within the data object, use the /describe endpoint to view the requirements for a given resource.

When sending a PUT request, the data object (request payload) requires both a data key and a fields key.

Example: Updating a Group Name
cURLPythonRubyResponse

curl \
	-H "Accept: application/json" \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
	-X PUT \
	"https://your.statseeker.server/api/v2.1/group/?indent=3" \
	-d '{"fields":{"name":{"field":"name","filter":{"query":"=\u0027<OLD GROUP NAME>\u0027"}}},"data":[{"name":"<NEW GROUP NAME>"}]}'

# import requests for handling connection and encoding
import requests
import json
def do_request(server, query, user, pword, reqData):
    # Run auth request
    headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
    url = f'https://{server}/ss-auth'
    authData = {'user': user, 'password': pword}
    resp = requests.post(url, headers=headers, data=authData, verify=False)
    headers['Content-Type'] = 'application/json'
    url = f'https://{server}/{query}'
    print(f'Get Auth Token: {resp.status_code}')
    if resp.status_code == 200:    
        # Authentication successful
        myToken = resp.json()
        headers['Authorization'] = f'Bearer {myToken["access_token"]}'
        resp = requests.put(url, headers=headers, data=reqData, verify=False)
    if resp.status_code == 401:
        print(f'Token auth failed: {resp.status_code}, trying basic auth')
        # Either Authentication was unsuccessful, or API set to use basic auth
        # Try basic auth
        resp = requests.put(url, headers=headers, auth=(user, pword), data=reqData, verify=False)
    return resp

# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'api_user'
pword = 'user_password'
# API root endpoint
query = 'api/v2.1'
# specify target endpoint
query += ''
# optional response formatting
query += '/?indent=3&links=none'
# data
reqData = json.dumps({"fields":{"name":{"field":"name","filter":{"query":"='<OLD GROUP NAME>'"}}},"data":[{"name":"<NEW GROUP NAME>"}]})
# Run the request
resp = do_request(server, query, user, pword, reqData)
if resp.status_code == 200:
    print(resp.status_code)
    print(resp.json())
else:
    print(f'Error: {resp.status_code} {resp.reason}')

# install with: $ gem install rest-client
require "rest_client"
require "json"
require "base64"

def try_basic(server, query, user, pword, reqData)
	headers = {
		:content_type => "application/json"
	}
	url = "https://" + server + "/" + query
	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
	return RestClient::Request.execute(
		:method => :put,
		:url => url,
		:headers => headers,
		:verify_ssl => false,
		:payload => reqData
	)
end

def do_request(server, query, user, pword, reqData)
    # Run auth request
    headers = {
        :content_type => "application/x-www-form-urlencoded"
    }
    url = "https://" + server + "/ss-auth"
    authData = {
       :user => user,
       :password => pword
    }
    begin
        resp = RestClient::Request.execute(
            :method => :post,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
            :payload => authData
        )
    rescue RestClient::Unauthorized
		# bad credentials
        try_basic(server, query, user, pword, reqData)
    else		
        # Authentication successful
		headers = {
		:content_type => "application/json"
		}	
        url = "https://" + server + "/" + query
        rdata = JSON.parse(resp)
        headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
        return RestClient::Request.execute(
			:method => :put,
			:url => url,
			:headers => headers,
			:verify_ssl => false,
			:payload => reqData
        )
    end
	rescue RestClient::Unauthorized
		# Statseeker may be configured for basic auth
        try_basic(server, query, user, pword, reqData)
end
# Statseeker Server IP
$server = 'your.statseeker.server'
# api user credentials
$user = 'api_user'
$pword = 'user_password'
# api root endpoint
$query = 'api/v2.1'
# specify target endpoint
$query += '/group'
# optional response formatting
$query += '/?indent=3&links=none'
# configure payload
$reqData = '{"fields":{"name":{"field":"name","filter":{"query":"=\'<OLD GROUP NAME>\'"}}},"data":[{"name":"<NEW GROUP NAME>"}]}'
# Run the request
resp = do_request($server, $query, $user, $pword, $reqData)
puts "#{resp.to_str}"


{
  "info": "The Statseeker RESTful API",
  "data": {
    "errmsg": "ok",
    "success": true,
    "time": 1496190511
  },
  "api_version": "2.1"
}

[top]

DELETE

Use the DELETE request to delete an existing instance of the specified resource. The data object included must be a json string with a single fields key. Some resource types will require additional keys within the data object, use the /describe endpoint to view the requirements for a given resource.

[top]

Example: Deleting Multiple Groups

We will be deleting all groups with a name matching a specified filter string.

cURLPythonRubyResponse

curl \
	-H "Accept: application/json" \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
	-X DELETE \
	"https://your.statseeker.server/api/v2.1/group/?indent=3" \ 
	-d '{"fields":{"name":{"field":"name","filter":{"query":"LIKE \u0027<FILTER STRING>\u0027"}}}}'


# import requests for handling connection and encoding
import requests
import json
def do_request(server, query, user, pword, reqData):
    # Run auth request
    headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
    url = f'https://{server}/ss-auth'
    authData = {'user': user, 'password': pword}
    resp = requests.post(url, headers=headers, data=authData, verify=False)
    headers['Content-Type'] = 'application/json'
    url = f'https://{server}/{query}'
    print(f'Get Auth Token: {resp.status_code}')
    if resp.status_code == 200:    
        # Authentication successful
        myToken = resp.json()
        headers['Authorization'] = f'Bearer {myToken["access_token"]}'
        resp = requests.delete(url, headers=headers, data=reqData, verify=False)
    if resp.status_code == 401:
        print(f'Token auth failed: {resp.status_code}, trying basic auth')
        # Either Authentication was unsuccessful, or API set to use basic auth
        # Try basic auth
        resp = requests.delete(url, headers=headers, auth=(user, pword), data=reqData, verify=False)
    return resp

# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'api_user'
pword = 'user_password'
# API root endpoint
query = 'api/v2.1'
# specify target endpoint
query += '/group'
# optional response formatting
query += '/?indent=3&links=none'
# data
reqData = json.dumps({"fields":{"name":{"field":"name","filter":{"query":"LIKE '<FILTER STRING>'"}}}})
# Run the request
resp = do_request(server, query, user, pword, reqData)
if resp.status_code == 200:
    print(resp.status_code)
    print(resp.json())
else:
    print(f'Error: {resp.status_code} {resp.reason}')

# install with: $ gem install rest-client
require "rest_client"
require "json"
require "base64"

def try_basic(server, query, user, pword, reqData)
	headers = {
		:content_type => "application/json"
	}
	url = "https://" + server + "/" + query
	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
	return RestClient::Request.execute(
		:method => :delete,
		:url => url,
		:headers => headers,
		:verify_ssl => false,
		:payload => reqData
	)
end

def do_request(server, query, user, pword, reqData)
    # Run auth request
    headers = {
        :content_type => "application/x-www-form-urlencoded"
    }
    url = "https://" + server + "/ss-auth"
    authData = {
       :user => user,
       :password => pword
    }
    begin
        resp = RestClient::Request.execute(
            :method => :post,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
            :payload => authData
        )
    rescue RestClient::Unauthorized
		# bad credentials
        try_basic(server, query, user, pword, reqData)
    else		
        # Authentication successful
		headers = {
		:content_type => "application/json"
		}	
        url = "https://" + server + "/" + query
        rdata = JSON.parse(resp)
        headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
        return RestClient::Request.execute(
			:method => :delete,
			:url => url,
			:headers => headers,
			:verify_ssl => false,
			:payload => reqData
        )
    end
	rescue RestClient::Unauthorized
		# Statseeker may be configured for basic auth
        try_basic(server, query, user, pword, reqData)
end
# Statseeker Server IP
$server = 'your.statseeker.server'
# api user credentials
$user = 'api_user'
$pword = 'user_password'
# api root endpoint
$query = 'api/v2.1'
# specify target endpoint
$query += '/group'
# optional response formatting
$query += '/?indent=3&links=none'
# configure payload
$reqData = '{"fields":{"name":{"field":"name","filter":{"query":"LIKE \'<FILTER STRING>\'"}}}}'
# Run the request
resp = do_request($server, $query, $user, $pword, $reqData)
puts "#{resp.to_str}"



{
   "version":"2.1",
   "revision":"11",
   "info":"The Statseeker RESTful API",
   "data":{
      "success":true,
      "errmsg":"ok",
      "time":1623638287
   }
}
[top]

The Describe Endpoint (/api/v2.1/{resource}/describe)

The /describe endpoint is particularly useful as it allows you to query a specified resource to return details on the resource.

The response from a GET request targeting the {resource}/describe endpoint will contain:

  • Resource name, title and description
  • All fields pertaining to the resource
  • All data formats that can be applied to each field
  • All request methods that can be applied to the resource
  • All fields and data that can be used with each request method
  • Details on all links between the selected resource and any other resources
  • Whether or not the resource allows the use of custom defined formula fields
  • An info block presenting data structure details such as resource inheritance relationships and data functionality options such as whether or not the resource can be grouped or reported on

The various HTTP request types are mapped to commands within the API.

HTTP Request Method API Command
GET get
POST add
PUT update
DELETE delete

The /describe endpoint can be applied to any resources returned from a GET request applied to the root endpoint.
I.e.https://your.statseeker.server/api/v2.1/ will return all resources available to the Statseeker installation, and any of these can have /describe applied to return details on the resource.

[top]

GET

The parameters that may be passed when sending a GET request.

Parameters Type/Valid Values Description
links
  • only - only return the links object, no data object
  • none - only return the data object, no links object
  • html - return html links. If the response is being displayed in a browser then the links may be clicked to send a GET request for the associated object/field.
  • htmlonly - only return html links, no data object
Modifies how the links contained within the response object are presented
indent positive integer Number of characters to indent when formatting code blocks for display

[top]

Example: Requesting a /describe on the User Resource
cURLPythonRubyResponse

curl \
	-H "Accept: application/json" \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
	-X GET \
	"https://your.statseeker.server1/api/v2.1/user/describe/?indent=3"


# import requests for handling connection and encoding
import requests
import json
def do_request(server, query, user, pword):
    # Run auth request
    headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
    url = f'https://{server}/ss-auth'
    authData = {'user': user, 'password': pword}
    resp = requests.post(url, headers=headers, data=authData, verify=False)
    headers['Content-Type'] = 'application/json'
    url = f'https://{server}/{query}'
    print(f'Get Auth Token: {resp.status_code}')
    if resp.status_code == 200:    
        # Authentication successful
        myToken = resp.json()
        headers['Authorization'] = f'Bearer {myToken["access_token"]}'
        resp = requests.get(url, headers=headers, verify=False)
    if resp.status_code == 401:
        print(f'Token auth failed: {resp.status_code}, trying basic auth')
        # Either Authentication was unsuccessful, or API set to use basic auth
        # Try basic auth
        resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
    return resp

# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'api_user'
pword = 'user_password'
# API root endpoint
query = 'api/v2.1'
# specify target endpoint
query += 'user/describe'
# optional response formatting
query += '/?indent=3&links=none'
# Run the request
resp = do_request(server, query, user, pword)
if resp.status_code == 200:
    print(resp.status_code)
    print(resp.json())
else:
    print(f'Error: {resp.status_code} {resp.reason}') 


# install with: $ gem install rest-client
require "rest_client"
require "json"
require "base64"

def try_basic(server, query, user, pword)
	headers = {
		:content_type => "json"
	}
	url = "https://" + server + "/" + query
	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
	return RestClient::Request.execute(
		:method => :get,
		:url => url,
		:headers => headers,
		:verify_ssl => false
	)
end

def do_request(server, query, user, pword)
    # Run auth request
    headers = {
        :content_type => "application/x-www-form-urlencoded"
    }
    url = "https://" + server + "/ss-auth"
    authData = {
       :user => user,
       :password => pword
    }
    begin
        resp = RestClient::Request.execute(
            :method => :post,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
            :payload => authData
        )
    rescue RestClient::Unauthorized
		# bad credentials
        try_basic(server, query, user, pword)
    else
        # Authentication successful
        headers = {
			:content_type => "application/json"
		}	
        url = "https://" + server + "/" + query
        rdata = JSON.parse(resp)
        headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
        return RestClient::Request.execute(
            :method => :get,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
        )
    end
	rescue RestClient::Unauthorized
		# Statseeker may be configured for basic auth
        try_basic(server, query, user, pword)
end
# Statseeker Server IP
$server = 'your.statseeker.server'
# api user credentials
$user = 'api_user'
$pword = 'user_password'
# api root endpoint
$query = 'api/v2.1'
# specify target endpoint
$query += 'user/describe'
# optional response formatting
$query += '/?indent=3&links=none'
# Run the request
resp = do_request($server, $query, $user, $pword)
puts "#{resp.to_str}"

{
{
    "version": "2.1",
    "revision": "13",
    "info": "The Statseeker RESTful API",
    "data": {
        "success": true,
        "errmsg": "ok",
        "time": 1646798321,
        "objects": [
            {
                "title": "User",
                "type": "user",
                "description": "Statseeker Users",
                "commands": {
                    "describe": {
                        "valid_fields": null,
                        "valid_data": null
                    },
                    "add": {
                        "valid_data": {
                            "name": {
                                "required": true
                            },
                            "tz": {
                                "required": false
                            },
                            "top_n": {
                                "required": false
                            },
                            "email": {
                                "required": false
                            },
                            "reportRowSpacing": {
                                "required": false
                            },
                            "exportDateFormat": {
                                "required": false
                            },
                            "auth_ttl": {
                                "required": false
                            },
                            "api": {
                                "required": false
                            },
                            "auth": {
                                "required": false
                            },
                            "auth_refresh": {
                                "required": false
                            },
                            "password": {
                                "required": false
                            },
                            "is_admin": {
                                "required": false
                            }
                        },
                        "valid_fields": null
                    },
                    "update": {
                        "valid_fields": {
                            "auth": {
                                "required": false
                            },
                            "auth_refresh": {
                                "required": false
                            },
                            "id": {
                                "required": false
                            },
                            "is_admin": {
                                "required": false
                            },
                            "password": {
                                "required": false
                            },
                            "name": {
                                "required": false
                            },
                            "tz": {
                                "required": false
                            },
                            "top_n": {
                                "required": false
                            },
                            "email": {
                                "required": false
                            },
                            "reportRowSpacing": {
                                "required": false
                            },
                            "api": {
                                "required": false
                            },
                            "auth_ttl": {
                                "required": false
                            },
                            "exportDateFormat": {
                                "required": false
                            }
                        },
                        "valid_data": {
                            "reportRowSpacing": {
                                "required": false
                            },
                            "api": {
                                "required": false
                            },
                            "exportDateFormat": {
                                "required": false
                            },
                            "auth_ttl": {
                                "required": false
                            },
                            "tz": {
                                "required": false
                            },
                            "top_n": {
                                "required": false
                            },
                            "email": {
                                "required": false
                            },
                            "is_admin": {
                                "required": false
                            },
                            "password": {
                                "required": false
                            },
                            "auth_refresh": {
                                "required": false
                            },
                            "auth": {
                                "required": false
                            }
                        }
                    },
                    "get": {
                        "valid_fields": {
                            "email": {
                                "required": false
                            },
                            "tz": {
                                "required": false
                            },
                            "top_n": {
                                "required": false
                            },
                            "name": {
                                "required": false
                            },
                            "api": {
                                "required": false
                            },
                            "auth_ttl": {
                                "required": false
                            },
                            "exportDateFormat": {
                                "required": false
                            },
                            "reportRowSpacing": {
                                "required": false
                            },
                            "auth_refresh": {
                                "required": false
                            },
                            "auth": {
                                "required": false
                            },
                            "is_admin": {
                                "required": false
                            },
                            "password": {
                                "required": false
                            },
                            "id": {
                                "required": false
                            }
                        },
                        "valid_data": null
                    },
                    "delete": {
                        "valid_fields": {
                            "email": {
                                "required": false
                            },
                            "name": {
                                "required": false
                            },
                            "tz": {
                                "required": false
                            },
                            "top_n": {
                                "required": false
                            },
                            "exportDateFormat": {
                                "required": false
                            },
                            "auth_ttl": {
                                "required": false
                            },
                            "api": {
                                "required": false
                            },
                            "reportRowSpacing": {
                                "required": false
                            },
                            "auth": {
                                "required": false
                            },
                            "auth_refresh": {
                                "required": false
                            },
                            "id": {
                                "required": false
                            },
                            "password": {
                                "required": false
                            },
                            "is_admin": {
                                "required": false
                            }
                        },
                        "valid_data": null
                    }
                },
                "fields": {
                    "email": {
                        "title": "Email",
                        "description": "User email address",
                        "datatype": "string"
                    },
                    "name": {
                        "description": "User name",
                        "datatype": "string",
                        "title": "Name"
                    },
                    "tz": {
                        "description": "User time zone",
                        "datatype": "string",
                        "title": "Time Zone"
                    },
                    "top_n": {
                        "description": "The default Top N number for the user",
                        "datatype": "integer",
                        "title": "Top N"
                    },
                    "exportDateFormat": {
                        "description": "User specified Date Format",
                        "datatype": "string",
                        "title": "Date Format"
                    },
                    "auth_ttl": {
                        "description": "The TTL for authentication tokens (in seconds)",
                        "datatype": "integer",
                        "title": "Authentication TTL"
                    },
                    "api": {
                        "description": "User API access permission",
                        "datatype": "string",
                        "title": "API Access"
                    },
                    "reportRowSpacing": {
                        "datatype": "string",
                        "description": "The report row spacing preference for the user",
                        "title": "Report Row Spacing"
                    },
                    "auth": {
                        "datatype": "string",
                        "description": "User authentication method",
                        "title": "Authentication method"
                    },
                    "auth_refresh": {
                        "description": "The time allowed after a token has expired that it will be refreshed (in seconds)",
                        "datatype": "integer",
                        "title": "Authentication Refresh"
                    },
                    "id": {
                        "title": "ID",
                        "description": "User Identifier",
                        "datatype": "integer"
                    },
                    "password": {
                        "title": "Password",
                        "description": "User password",
                        "datatype": "string"
                    },
                    "is_admin": {
                        "title": "Is Admin",
                        "datatype": "integer",
                        "description": "Whether the user has admin access"
                    }
                },
                "info": {
                    "allow_grouping": 1
                },
                "allow_formula_fields": true,
                "links": {},
                "global_field_options": {
                    "aggregation_format": {
                        "description": "Aggregation formats to apply when group_by option is provided",
                        "values": {
                            "first": {
                                "title": "First",
                                "description": "First value in the group (default)"
                            },
                            "last": {
                                "title": "Last",
                                "description": "Last value in the group"
                            },
                            "avg": {
                                "title": "Average",
                                "description": "Average of the values in the group"
                            },
                            "count": {
                                "title": "Count",
                                "description": "Number on non-null values in the group"
                            },
                            "count_all": {
                                "title": "Count (include NULL)",
                                "description": "Number of values in the group (including null values)"
                            },
                            "count_unique": {
                                "title": "Unique count",
                                "description": "Number of unique non-null values in the group"
                            },
                            "count_unique_all": {
                                "title": "Unique count (include NULL)",
                                "description": "Number of unique values in the group (including null values)"
                            },
                            "cat": {
                                "title": "Concatenate",
                                "description": "Concatenation of the values in the group"
                            },
                            "list": {
                                "title": "List",
                                "description": "Comma separated concatenation of the values in the group"
                            },
                            "list_unique": {
                                "title": "Unique List",
                                "description": "Comma separated concatenation of the unique values in the group"
                            },
                            "min": {
                                "title": "Minimum",
                                "description": "Minimum of the values in the group"
                            },
                            "max": {
                                "title": "Maximum",
                                "description": "Maximum of the values in the group"
                            },
                            "sum": {
                                "title": "Sum",
                                "description": "Sum of all values in the group (null if no valid values)"
                            },
                            "total": {
                                "title": "Total",
                                "description": "Sum of all values in the group (0 if no valid values)"
                            },
                            "median": {
                                "title": "Median",
                                "description": "Median of the values in the group"
                            },
                            "95th": {
                                "title": "95th percentile",
                                "description": "95th percentile of the values in the group"
                            },
                            "stddev": {
                                "title": "Standard deviation",
                                "description": "Standard deviation of the values in the group"
                            }
                        }
                    }
                }
            }
        ]
    },
    "links": [
        {
            "link": "/api/v2.1/user/describe",
            "rel": "self"
        },
        {
            "link": "/api/v2.1",
            "rel": "base"
        },
        {
            "link": "/api/v2.1/user",
            "rel": "collection"
        }
    ]
}
[top]

Example: Requesting a /describe on the Device Resource (cdt_device)
cURLPythonRubyResponse

curl \
	-H "Accept: application/json" \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
	-X GET \
	"https://your.statseeker.server1/api/v2.1/cdt_device/describe/?indent=3"


# import requests for handling connection and encoding
import requests
import json
def do_request(server, query, user, pword):
    # Run auth request
    headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
    url = f'https://{server}/ss-auth'
    authData = {'user': user, 'password': pword}
    resp = requests.post(url, headers=headers, data=authData, verify=False)
    headers['Content-Type'] = 'application/json'
    url = f'https://{server}/{query}'
    print(f'Get Auth Token: {resp.status_code}')
    if resp.status_code == 200:    
        # Authentication successful
        myToken = resp.json()
        headers['Authorization'] = f'Bearer {myToken["access_token"]}'
        resp = requests.get(url, headers=headers, verify=False)
    if resp.status_code == 401:
        print(f'Token auth failed: {resp.status_code}, trying basic auth')
        # Either Authentication was unsuccessful, or API set to use basic auth
        # Try basic auth
        resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
    return resp

# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'api_user'
pword = 'user_password'
# API root endpoint
query = 'api/v2.1'
# specify target endpoint
query += 'cdt_device/describe'
# optional response formatting
query += '/?indent=3&links=none'
# Run the request
resp = do_request(server, query, user, pword)
if resp.status_code == 200:
    print(resp.status_code)
    print(resp.json())
else:
    print(f'Error: {resp.status_code} {resp.reason}') 


# install with: $ gem install rest-client
require "rest_client"
require "json"
require "base64"

def try_basic(server, query, user, pword)
	headers = {
		:content_type => "json"
	}
	url = "https://" + server + "/" + query
	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
	return RestClient::Request.execute(
		:method => :get,
		:url => url,
		:headers => headers,
		:verify_ssl => false
	)
end

def do_request(server, query, user, pword)
    # Run auth request
    headers = {
        :content_type => "application/x-www-form-urlencoded"
    }
    url = "https://" + server + "/ss-auth"
    authData = {
       :user => user,
       :password => pword
    }
    begin
        resp = RestClient::Request.execute(
            :method => :post,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
            :payload => authData
        )
    rescue RestClient::Unauthorized
		# bad credentials
        try_basic(server, query, user, pword)
    else
        # Authentication successful
        headers = {
			:content_type => "application/json"
		}	
        url = "https://" + server + "/" + query
        rdata = JSON.parse(resp)
        headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
        return RestClient::Request.execute(
            :method => :get,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
        )
    end
	rescue RestClient::Unauthorized
		# Statseeker may be configured for basic auth
        try_basic(server, query, user, pword)
end
# Statseeker Server IP
$server = 'your.statseeker.server'
# api user credentials
$user = 'api_user'
$pword = 'user_password'
# api root endpoint
$query = 'api/v2.1'
# specify target endpoint
$query += 'cdt_device/describe'
# optional response formatting
$query += '/?indent=3&links=none'
# Run the request
resp = do_request($server, $query, $user, $pword)
puts "#{resp.to_str}"

{
{
    "version": "2.1",
    "revision": "13",
    "info": "The Statseeker RESTful API",
    "data": {
        "success": true,
        "errmsg": "ok",
        "time": 1646798484,
        "objects": [
            {
                "type": "cdt_device",
                "title": "Device",
                "description": "The custom data entities for the device table",
                "fields": {
                    "id": {
                        "title": "ID",
                        "description": "The entity identifier",
                        "datatype": "integer"
                    },
                    "name": {
                        "title": "Name",
                        "description": "The entity name",
                        "datatype": "string"
                    },
                    "deviceid": {
                        "title": "Device ID",
                        "description": "The ID of the parent device",
                        "datatype": "integer"
                    },
                    "idx": {
                        "title": "Index",
                        "description": "The base SNMP index for this entity",
                        "datatype": "string"
                    },
                    "table": {
                        "title": "Table",
                        "description": "The table to which the entity belongs",
                        "datatype": "string"
                    },
                    "poll": {
                        "title": "Poll State",
                        "description": "The poll state of the entity",
                        "datatype": "string"
                    },
                    "auth_method": {
                        "title": "SNMPv3 Authentication Method",
                        "description": "Authentication method for SNMPv3 devices",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "auth_pass": {
                        "title": "SNMPv3 Authentication Password",
                        "description": "Authentication password for SNMPv3 devices",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "auth_user": {
                        "title": "SNMPv3 Authentication Username",
                        "description": "Authentication user for SNMPv3 devices",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "community": {
                        "title": "Community",
                        "description": "The community string status of the device",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "context": {
                        "title": "SNMPv3 Context",
                        "description": "Context for SNMPv3 devices",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "custom_data_details": {
                        "title": "Custom Data Details",
                        "description": "A JSON string object indicating which custom entities have been found during a discovery",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "discover_getNext": {
                        "title": "Use GetNext",
                        "description": "Walk this device using SNMP getNext instead of getBulk",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "discover_minimal": {
                        "title": "Use Minimal Walk",
                        "description": "Walk this device using a minimal set of oids",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "discover_snmpv1": {
                        "title": "Use SNMPv1",
                        "description": "Walk this device using SNMPv1",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "hostname": {
                        "title": "Hostname",
                        "description": "The hostname of the device",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "ipaddress": {
                        "title": "IP Address",
                        "description": "The IP address of the device",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "latitude": {
                        "title": "Latitude",
                        "description": "The user defined latitude of the device's location",
                        "polltype": "cfg",
                        "datatype": "float"
                    },
                    "longitude": {
                        "title": "Longitude",
                        "description": "The user defined longitude of the device's location",
                        "polltype": "cfg",
                        "datatype": "float"
                    },
                    "manual_name": {
                        "title": "User Defined Name",
                        "description": "The user defined name of the device",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "memorySize": {
                        "title": "Memory Size",
                        "description": "The amount of physical read-write memory contained by the entity",
                        "polltype": "cfg",
                        "units": "bytes",
                        "symbol": "B",
                        "datatype": "integer"
                    },
                    "mis": {
                        "title": "MAC/IP/Switch Collection State",
                        "description": "Include this device in the MIS report calculations",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "ping_dup": {
                        "title": "Ping Duplicate",
                        "description": "Number of duplicate ping responses received",
                        "polltype": "tsc",
                        "interval": 3600,
                        "datatype": "integer",
                        "options": {
                            "value_time": {
                                "description": "The timestamp for a timeseries event",
                                "values": {
                                    "none": "Do not return a timestamp",
                                    "mid": "The midpoint of the start and end timestamps",
                                    "end": "The timestamp at which the event finished",
                                    "start": "The timestamp at which the event began",
                                    "all": "An array of start, mid and end"
                                }
                            },
                            "formats": {
                                "description": "The valid data formats",
                                "values": {
                                    "median": {
                                        "description": "Median of the data",
                                        "title": "Median"
                                    },
                                    "trendline_daily_change": {
                                        "title": "Trendline daily change",
                                        "description": "Slope of the trendline (units/day)"
                                    },
                                    "anomaly_metric": {
                                        "description": "Metric from -100 to 100 indicating whether requested timeseries values are unusually large or small",
                                        "title": "Anomaly metric"
                                    },
                                    "trendline_upr": {
                                        "datatype": "array",
                                        "description": "Trendline confidence interval values (upper)",
                                        "title": "Trendline upper confidence interval"
                                    },
                                    "count": {
                                        "description": "Number of non-null data points",
                                        "title": "Count"
                                    },
                                    "baseline": {
                                        "title": "Baseline",
                                        "description": "List of expected baseline values calculated from historical data. Corresponds to 0% anomaly metric.",
                                        "datatype": "array"
                                    },
                                    "forecast_min": {
                                        "title": "Forecast minimum",
                                        "description": "Lower boundary of feasible forecast value range"
                                    },
                                    "trendline_strength": {
                                        "title": "Trendline strength",
                                        "description": "Coefficient of determination (R-squared) of the trendline"
                                    },
                                    "forecast_boundary_time": {
                                        "datatype": "time",
                                        "description": "Time forecast exceeds feasible value range if before end of timefilter range",
                                        "title": "Forecast boundary time"
                                    },
                                    "95th": {
                                        "description": "95th percentile of the data",
                                        "title": "95th percentile"
                                    },
                                    "forecast_daily_change": {
                                        "description": "The average daily change of forecast values",
                                        "title": "Forecast daily change"
                                    },
                                    "min": {
                                        "description": "Minimum data value",
                                        "title": "Minimum"
                                    },
                                    "forecast_max": {
                                        "title": "Forecast maximum",
                                        "description": "Upper boundary of feasible forecast value range"
                                    },
                                    "current": {
                                        "title": "Current",
                                        "description": "The current value"
                                    },
                                    "baseline_percent_compare": {
                                        "description": "Percentage difference between data average and expected baseline calculated from historical data",
                                        "title": "Baseline Percent Comparison"
                                    },
                                    "start_tz_offset": {
                                        "datatype": "integer",
                                        "title": "Start TZ offset",
                                        "description": "The timezone offset of the first data point"
                                    },
                                    "forecast_vals": {
                                        "datatype": "array",
                                        "title": "Forecast values",
                                        "description": "An array of forecast values with periodic deviations at peak and offpeak times"
                                    },
                                    "max": {
                                        "title": "Maximum",
                                        "description": "Maximum data value"
                                    },
                                    "trendline_lwr": {
                                        "datatype": "array",
                                        "description": "Trendline confidence interval values (lower)",
                                        "title": "Trendline lower confidence interval"
                                    },
                                    "anomaly_strength": {
                                        "description": "Metric from 0 to 100 indicating whether requested timeseries values are extreme or unusual",
                                        "title": "Anomaly strength"
                                    },
                                    "forecast_predict_offpeak": {
                                        "description": "Long term prediction value calculated from historical data at offpeak times",
                                        "title": "Forecast prediction offpeak"
                                    },
                                    "start_time": {
                                        "datatype": "time",
                                        "title": "Start time",
                                        "description": "Time of the first data point"
                                    },
                                    "stddev": {
                                        "title": "Standard deviation",
                                        "description": "Standard deviation of the data"
                                    },
                                    "baseline_lwr": {
                                        "description": "List of baseline lower confidence interval values. Corresponds to -95% anomaly metric.",
                                        "title": "Baseline Lower Bound",
                                        "datatype": "array"
                                    },
                                    "trendline_percent_change": {
                                        "description": "Trendline change scaled by the average of data over requested time filter",
                                        "title": "Trendline percent change"
                                    },
                                    "vals": {
                                        "description": "Timeseries data values",
                                        "title": "Values",
                                        "datatype": "array"
                                    },
                                    "cvals": {
                                        "datatype": "array",
                                        "description": "Cumulative data values",
                                        "title": "Cumulative Values"
                                    },
                                    "last": {
                                        "title": "Last",
                                        "description": "The last value in the data"
                                    },
                                    "trendline_start": {
                                        "title": "Trendline Start",
                                        "description": "Value of the first trendline data point"
                                    },
                                    "forecast_fit": {
                                        "datatype": "array",
                                        "title": "Forecast fit",
                                        "description": "An array of forecast values without periodic deviations at peak and offpeak times"
                                    },
                                    "baseline_compare": {
                                        "description": "Difference between data average and expected baseline calculated from historical data",
                                        "title": "Baseline Comparison"
                                    },
                                    "first": {
                                        "title": "First",
                                        "description": "The first value in the data"
                                    },
                                    "percentile": {
                                        "title": "Percentile",
                                        "description": "Custom percentile of the data"
                                    },
                                    "trendline_predict": {
                                        "title": "Trendline Predict",
                                        "description": "Prediction value from the trendline"
                                    },
                                    "trendline_change": {
                                        "description": "Trendline change over the requested timefilter range",
                                        "title": "Trendline change"
                                    },
                                    "baseline_upr": {
                                        "title": "Baseline Upper Bound",
                                        "description": "List of baseline upper confidence interval values. Corresponds to 95% anomaly metric.",
                                        "datatype": "array"
                                    },
                                    "avg": {
                                        "title": "Average",
                                        "description": "Average of the data"
                                    },
                                    "baseline_avg": {
                                        "description": "Average of expected baseline values calculated from historical data. Corresponds to 0% anomaly metric.",
                                        "title": "Baseline Average"
                                    },
                                    "trendline_finish": {
                                        "title": "Trendline Finish",
                                        "description": "Value of the last trendline data point"
                                    },
                                    "total": {
                                        "description": "Sum of the data",
                                        "title": "Total"
                                    },
                                    "forecast_predict": {
                                        "description": "Long term prediction value calculated from historical data",
                                        "title": "Forecast prediction"
                                    },
                                    "forecast_predict_peak": {
                                        "description": "Long term prediction value calculated from historical data at peak times",
                                        "title": "Forecast prediction peak"
                                    },
                                    "trendline_fit": {
                                        "description": "Trendline data values",
                                        "title": "Trendline fit",
                                        "datatype": "array"
                                    }
                                }
                            },
                            "stats": {
                                "values": {
                                    "forecast": {
                                        "values": {
                                            "min": {
                                                "description": "Manually set lower boundary of feasible forecast value range",
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": null,
                                                "title": "Minimum"
                                            },
                                            "data_range": {
                                                "title": "Baseline History",
                                                "default": "range = now - 180d to now",
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "description": "Timefilter for the historical data range used to calculate forecasts. Default is last 180 days.",
                                                "values": null
                                            },
                                            "predict_time": {
                                                "values": null,
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak"
                                                ],
                                                "description": "Time to use for the forecast_predict, forecast_predict_peak or forecast_predict_offpeak values (e.g. now + 10d)",
                                                "title": "Predict Time"
                                            },
                                            "max": {
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": null,
                                                "description": "Manually set upper boundary of feasible forecast value range",
                                                "title": "Maximum"
                                            },
                                            "is_cumulative": {
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_change",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "title": "Is Cumulative",
                                                "description": "whether to use cumulative forecasts",
                                                "default": false
                                            }
                                        },
                                        "description": "Forecast related input options"
                                    },
                                    "percentile": {
                                        "title": "Percentile",
                                        "values": null,
                                        "valid_formats": [
                                            "percentile"
                                        ],
                                        "description": "The value to use for the percentile format (between 0 and 100)"
                                    },
                                    "baseline": {
                                        "description": "Baseline and anomaly metric related input options",
                                        "values": {
                                            "percentile": {
                                                "description": "Baseline percentile to output",
                                                "valid_formats": [
                                                    "baseline_avg",
                                                    "baseline_compare",
                                                    "baseline_percent_compare",
                                                    "baseline"
                                                ],
                                                "default": 50,
                                                "values": null,
                                                "title": "Percentile"
                                            },
                                            "data_range": {
                                                "title": "Baseline History",
                                                "description": "Timefilter for the historical data range used to calculate baseline and anomaly metric. Default is last 180 days.",
                                                "valid_formats": [
                                                    "baseline_avg",
                                                    "baseline_compare",
                                                    "baseline_percent_compare",
                                                    "baseline",
                                                    "baseline_lwr",
                                                    "baseline_upr",
                                                    "anomaly_metric",
                                                    "anomaly_strength"
                                                ],
                                                "default": "range = now - 180d to now",
                                                "values": null
                                            },
                                            "lwr_percentile": {
                                                "title": "Lower Percentile",
                                                "description": "Baseline percentile to output for baseline lower bound",
                                                "valid_formats": [
                                                    "baseline_lwr"
                                                ],
                                                "default": 2.5,
                                                "values": null
                                            },
                                            "upr_percentile": {
                                                "valid_formats": [
                                                    "baseline_upr"
                                                ],
                                                "default": 97.5,
                                                "values": null,
                                                "description": "Baseline percentile to output for baseline upper bound",
                                                "title": "Upper Percentile"
                                            }
                                        }
                                    },
                                    "trendline": {
                                        "description": "Trendline related input options",
                                        "values": {
                                            "lwr_stddev": {
                                                "valid_formats": [
                                                    "trendline_lwr"
                                                ],
                                                "description": "The number of standard deviations to use for the trendline_lwr format",
                                                "values": null,
                                                "title": "Lower Standard Deviation"
                                            },
                                            "upr_stddev": {
                                                "title": "Upper Standard Deviation",
                                                "valid_formats": [
                                                    "trendline_upr"
                                                ],
                                                "description": "The number of standard deviations to use for the trendline_upr format",
                                                "values": null
                                            },
                                            "is_cumulative": {
                                                "title": "Is Cumulative",
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "valid_formats": [
                                                    "trendline_fit",
                                                    "trendline_predict"
                                                ],
                                                "description": "whether to use cumulative trendline"
                                            },
                                            "predict_time": {
                                                "title": "Predict Time",
                                                "valid_formats": [
                                                    "trendline_predict"
                                                ],
                                                "values": null,
                                                "description": "The time to use for the trendline_predict value"
                                            },
                                            "constrained": {
                                                "valid_formats": [
                                                    "trendline_start",
                                                    "trendline_finish",
                                                    "trendline_daily_change",
                                                    "trendline_change",
                                                    "trendline_percent_change",
                                                    "trendline_predict"
                                                ],
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "default": true,
                                                "description": "Whether to use a constrained trendline",
                                                "title": "Constrained"
                                            }
                                        },
                                        "title": "Trendline"
                                    }
                                },
                                "description": "Additional input options for certain formats"
                            },
                            "timefmt": {
                                "description": "Format a timestamp into a human readable string. Format specifier is identical to strftime(3)",
                                "values": null
                            }
                        }
                    },
                    "ping_lost1": {
                        "title": "Ping Lost 1",
                        "description": "Number of times that a single ping request is lost",
                        "polltype": "tsc",
                        "interval": 3600,
                        "datatype": "integer",
                        "options": {
                            "value_time": {
                                "description": "The timestamp for a timeseries event",
                                "values": {
                                    "none": "Do not return a timestamp",
                                    "mid": "The midpoint of the start and end timestamps",
                                    "end": "The timestamp at which the event finished",
                                    "start": "The timestamp at which the event began",
                                    "all": "An array of start, mid and end"
                                }
                            },
                            "formats": {
                                "description": "The valid data formats",
                                "values": {
                                    "median": {
                                        "description": "Median of the data",
                                        "title": "Median"
                                    },
                                    "trendline_daily_change": {
                                        "title": "Trendline daily change",
                                        "description": "Slope of the trendline (units/day)"
                                    },
                                    "anomaly_metric": {
                                        "description": "Metric from -100 to 100 indicating whether requested timeseries values are unusually large or small",
                                        "title": "Anomaly metric"
                                    },
                                    "trendline_upr": {
                                        "datatype": "array",
                                        "description": "Trendline confidence interval values (upper)",
                                        "title": "Trendline upper confidence interval"
                                    },
                                    "count": {
                                        "description": "Number of non-null data points",
                                        "title": "Count"
                                    },
                                    "baseline": {
                                        "title": "Baseline",
                                        "description": "List of expected baseline values calculated from historical data. Corresponds to 0% anomaly metric.",
                                        "datatype": "array"
                                    },
                                    "forecast_min": {
                                        "title": "Forecast minimum",
                                        "description": "Lower boundary of feasible forecast value range"
                                    },
                                    "trendline_strength": {
                                        "title": "Trendline strength",
                                        "description": "Coefficient of determination (R-squared) of the trendline"
                                    },
                                    "forecast_boundary_time": {
                                        "datatype": "time",
                                        "description": "Time forecast exceeds feasible value range if before end of timefilter range",
                                        "title": "Forecast boundary time"
                                    },
                                    "95th": {
                                        "description": "95th percentile of the data",
                                        "title": "95th percentile"
                                    },
                                    "forecast_daily_change": {
                                        "description": "The average daily change of forecast values",
                                        "title": "Forecast daily change"
                                    },
                                    "min": {
                                        "description": "Minimum data value",
                                        "title": "Minimum"
                                    },
                                    "forecast_max": {
                                        "title": "Forecast maximum",
                                        "description": "Upper boundary of feasible forecast value range"
                                    },
                                    "current": {
                                        "title": "Current",
                                        "description": "The current value"
                                    },
                                    "baseline_percent_compare": {
                                        "description": "Percentage difference between data average and expected baseline calculated from historical data",
                                        "title": "Baseline Percent Comparison"
                                    },
                                    "start_tz_offset": {
                                        "datatype": "integer",
                                        "title": "Start TZ offset",
                                        "description": "The timezone offset of the first data point"
                                    },
                                    "forecast_vals": {
                                        "datatype": "array",
                                        "title": "Forecast values",
                                        "description": "An array of forecast values with periodic deviations at peak and offpeak times"
                                    },
                                    "max": {
                                        "title": "Maximum",
                                        "description": "Maximum data value"
                                    },
                                    "trendline_lwr": {
                                        "datatype": "array",
                                        "description": "Trendline confidence interval values (lower)",
                                        "title": "Trendline lower confidence interval"
                                    },
                                    "anomaly_strength": {
                                        "description": "Metric from 0 to 100 indicating whether requested timeseries values are extreme or unusual",
                                        "title": "Anomaly strength"
                                    },
                                    "forecast_predict_offpeak": {
                                        "description": "Long term prediction value calculated from historical data at offpeak times",
                                        "title": "Forecast prediction offpeak"
                                    },
                                    "start_time": {
                                        "datatype": "time",
                                        "title": "Start time",
                                        "description": "Time of the first data point"
                                    },
                                    "stddev": {
                                        "title": "Standard deviation",
                                        "description": "Standard deviation of the data"
                                    },
                                    "baseline_lwr": {
                                        "description": "List of baseline lower confidence interval values. Corresponds to -95% anomaly metric.",
                                        "title": "Baseline Lower Bound",
                                        "datatype": "array"
                                    },
                                    "trendline_percent_change": {
                                        "description": "Trendline change scaled by the average of data over requested time filter",
                                        "title": "Trendline percent change"
                                    },
                                    "vals": {
                                        "description": "Timeseries data values",
                                        "title": "Values",
                                        "datatype": "array"
                                    },
                                    "cvals": {
                                        "datatype": "array",
                                        "description": "Cumulative data values",
                                        "title": "Cumulative Values"
                                    },
                                    "last": {
                                        "title": "Last",
                                        "description": "The last value in the data"
                                    },
                                    "trendline_start": {
                                        "title": "Trendline Start",
                                        "description": "Value of the first trendline data point"
                                    },
                                    "forecast_fit": {
                                        "datatype": "array",
                                        "title": "Forecast fit",
                                        "description": "An array of forecast values without periodic deviations at peak and offpeak times"
                                    },
                                    "baseline_compare": {
                                        "description": "Difference between data average and expected baseline calculated from historical data",
                                        "title": "Baseline Comparison"
                                    },
                                    "first": {
                                        "title": "First",
                                        "description": "The first value in the data"
                                    },
                                    "percentile": {
                                        "title": "Percentile",
                                        "description": "Custom percentile of the data"
                                    },
                                    "trendline_predict": {
                                        "title": "Trendline Predict",
                                        "description": "Prediction value from the trendline"
                                    },
                                    "trendline_change": {
                                        "description": "Trendline change over the requested timefilter range",
                                        "title": "Trendline change"
                                    },
                                    "baseline_upr": {
                                        "title": "Baseline Upper Bound",
                                        "description": "List of baseline upper confidence interval values. Corresponds to 95% anomaly metric.",
                                        "datatype": "array"
                                    },
                                    "avg": {
                                        "title": "Average",
                                        "description": "Average of the data"
                                    },
                                    "baseline_avg": {
                                        "description": "Average of expected baseline values calculated from historical data. Corresponds to 0% anomaly metric.",
                                        "title": "Baseline Average"
                                    },
                                    "trendline_finish": {
                                        "title": "Trendline Finish",
                                        "description": "Value of the last trendline data point"
                                    },
                                    "total": {
                                        "description": "Sum of the data",
                                        "title": "Total"
                                    },
                                    "forecast_predict": {
                                        "description": "Long term prediction value calculated from historical data",
                                        "title": "Forecast prediction"
                                    },
                                    "forecast_predict_peak": {
                                        "description": "Long term prediction value calculated from historical data at peak times",
                                        "title": "Forecast prediction peak"
                                    },
                                    "trendline_fit": {
                                        "description": "Trendline data values",
                                        "title": "Trendline fit",
                                        "datatype": "array"
                                    }
                                }
                            },
                            "stats": {
                                "values": {
                                    "forecast": {
                                        "values": {
                                            "min": {
                                                "description": "Manually set lower boundary of feasible forecast value range",
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": null,
                                                "title": "Minimum"
                                            },
                                            "data_range": {
                                                "title": "Baseline History",
                                                "default": "range = now - 180d to now",
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "description": "Timefilter for the historical data range used to calculate forecasts. Default is last 180 days.",
                                                "values": null
                                            },
                                            "predict_time": {
                                                "values": null,
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak"
                                                ],
                                                "description": "Time to use for the forecast_predict, forecast_predict_peak or forecast_predict_offpeak values (e.g. now + 10d)",
                                                "title": "Predict Time"
                                            },
                                            "max": {
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": null,
                                                "description": "Manually set upper boundary of feasible forecast value range",
                                                "title": "Maximum"
                                            },
                                            "is_cumulative": {
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_change",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "title": "Is Cumulative",
                                                "description": "whether to use cumulative forecasts",
                                                "default": false
                                            }
                                        },
                                        "description": "Forecast related input options"
                                    },
                                    "percentile": {
                                        "title": "Percentile",
                                        "values": null,
                                        "valid_formats": [
                                            "percentile"
                                        ],
                                        "description": "The value to use for the percentile format (between 0 and 100)"
                                    },
                                    "baseline": {
                                        "description": "Baseline and anomaly metric related input options",
                                        "values": {
                                            "percentile": {
                                                "description": "Baseline percentile to output",
                                                "valid_formats": [
                                                    "baseline_avg",
                                                    "baseline_compare",
                                                    "baseline_percent_compare",
                                                    "baseline"
                                                ],
                                                "default": 50,
                                                "values": null,
                                                "title": "Percentile"
                                            },
                                            "data_range": {
                                                "title": "Baseline History",
                                                "description": "Timefilter for the historical data range used to calculate baseline and anomaly metric. Default is last 180 days.",
                                                "valid_formats": [
                                                    "baseline_avg",
                                                    "baseline_compare",
                                                    "baseline_percent_compare",
                                                    "baseline",
                                                    "baseline_lwr",
                                                    "baseline_upr",
                                                    "anomaly_metric",
                                                    "anomaly_strength"
                                                ],
                                                "default": "range = now - 180d to now",
                                                "values": null
                                            },
                                            "lwr_percentile": {
                                                "title": "Lower Percentile",
                                                "description": "Baseline percentile to output for baseline lower bound",
                                                "valid_formats": [
                                                    "baseline_lwr"
                                                ],
                                                "default": 2.5,
                                                "values": null
                                            },
                                            "upr_percentile": {
                                                "valid_formats": [
                                                    "baseline_upr"
                                                ],
                                                "default": 97.5,
                                                "values": null,
                                                "description": "Baseline percentile to output for baseline upper bound",
                                                "title": "Upper Percentile"
                                            }
                                        }
                                    },
                                    "trendline": {
                                        "description": "Trendline related input options",
                                        "values": {
                                            "lwr_stddev": {
                                                "valid_formats": [
                                                    "trendline_lwr"
                                                ],
                                                "description": "The number of standard deviations to use for the trendline_lwr format",
                                                "values": null,
                                                "title": "Lower Standard Deviation"
                                            },
                                            "upr_stddev": {
                                                "title": "Upper Standard Deviation",
                                                "valid_formats": [
                                                    "trendline_upr"
                                                ],
                                                "description": "The number of standard deviations to use for the trendline_upr format",
                                                "values": null
                                            },
                                            "is_cumulative": {
                                                "title": "Is Cumulative",
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "valid_formats": [
                                                    "trendline_fit",
                                                    "trendline_predict"
                                                ],
                                                "description": "whether to use cumulative trendline"
                                            },
                                            "predict_time": {
                                                "title": "Predict Time",
                                                "valid_formats": [
                                                    "trendline_predict"
                                                ],
                                                "values": null,
                                                "description": "The time to use for the trendline_predict value"
                                            },
                                            "constrained": {
                                                "valid_formats": [
                                                    "trendline_start",
                                                    "trendline_finish",
                                                    "trendline_daily_change",
                                                    "trendline_change",
                                                    "trendline_percent_change",
                                                    "trendline_predict"
                                                ],
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "default": true,
                                                "description": "Whether to use a constrained trendline",
                                                "title": "Constrained"
                                            }
                                        },
                                        "title": "Trendline"
                                    }
                                },
                                "description": "Additional input options for certain formats"
                            },
                            "timefmt": {
                                "description": "Format a timestamp into a human readable string. Format specifier is identical to strftime(3)",
                                "values": null
                            }
                        }
                    },
                    "ping_lost2": {
                        "title": "Ping Lost 2",
                        "description": "Number of times that two ping requests in a row have been lost",
                        "polltype": "tsc",
                        "interval": 3600,
                        "datatype": "integer",
                        "options": {
                            "value_time": {
                                "description": "The timestamp for a timeseries event",
                                "values": {
                                    "none": "Do not return a timestamp",
                                    "mid": "The midpoint of the start and end timestamps",
                                    "end": "The timestamp at which the event finished",
                                    "start": "The timestamp at which the event began",
                                    "all": "An array of start, mid and end"
                                }
                            },
                            "formats": {
                                "description": "The valid data formats",
                                "values": {
                                    "median": {
                                        "description": "Median of the data",
                                        "title": "Median"
                                    },
                                    "trendline_daily_change": {
                                        "title": "Trendline daily change",
                                        "description": "Slope of the trendline (units/day)"
                                    },
                                    "anomaly_metric": {
                                        "description": "Metric from -100 to 100 indicating whether requested timeseries values are unusually large or small",
                                        "title": "Anomaly metric"
                                    },
                                    "trendline_upr": {
                                        "datatype": "array",
                                        "description": "Trendline confidence interval values (upper)",
                                        "title": "Trendline upper confidence interval"
                                    },
                                    "count": {
                                        "description": "Number of non-null data points",
                                        "title": "Count"
                                    },
                                    "baseline": {
                                        "title": "Baseline",
                                        "description": "List of expected baseline values calculated from historical data. Corresponds to 0% anomaly metric.",
                                        "datatype": "array"
                                    },
                                    "forecast_min": {
                                        "title": "Forecast minimum",
                                        "description": "Lower boundary of feasible forecast value range"
                                    },
                                    "trendline_strength": {
                                        "title": "Trendline strength",
                                        "description": "Coefficient of determination (R-squared) of the trendline"
                                    },
                                    "forecast_boundary_time": {
                                        "datatype": "time",
                                        "description": "Time forecast exceeds feasible value range if before end of timefilter range",
                                        "title": "Forecast boundary time"
                                    },
                                    "95th": {
                                        "description": "95th percentile of the data",
                                        "title": "95th percentile"
                                    },
                                    "forecast_daily_change": {
                                        "description": "The average daily change of forecast values",
                                        "title": "Forecast daily change"
                                    },
                                    "min": {
                                        "description": "Minimum data value",
                                        "title": "Minimum"
                                    },
                                    "forecast_max": {
                                        "title": "Forecast maximum",
                                        "description": "Upper boundary of feasible forecast value range"
                                    },
                                    "current": {
                                        "title": "Current",
                                        "description": "The current value"
                                    },
                                    "baseline_percent_compare": {
                                        "description": "Percentage difference between data average and expected baseline calculated from historical data",
                                        "title": "Baseline Percent Comparison"
                                    },
                                    "start_tz_offset": {
                                        "datatype": "integer",
                                        "title": "Start TZ offset",
                                        "description": "The timezone offset of the first data point"
                                    },
                                    "forecast_vals": {
                                        "datatype": "array",
                                        "title": "Forecast values",
                                        "description": "An array of forecast values with periodic deviations at peak and offpeak times"
                                    },
                                    "max": {
                                        "title": "Maximum",
                                        "description": "Maximum data value"
                                    },
                                    "trendline_lwr": {
                                        "datatype": "array",
                                        "description": "Trendline confidence interval values (lower)",
                                        "title": "Trendline lower confidence interval"
                                    },
                                    "anomaly_strength": {
                                        "description": "Metric from 0 to 100 indicating whether requested timeseries values are extreme or unusual",
                                        "title": "Anomaly strength"
                                    },
                                    "forecast_predict_offpeak": {
                                        "description": "Long term prediction value calculated from historical data at offpeak times",
                                        "title": "Forecast prediction offpeak"
                                    },
                                    "start_time": {
                                        "datatype": "time",
                                        "title": "Start time",
                                        "description": "Time of the first data point"
                                    },
                                    "stddev": {
                                        "title": "Standard deviation",
                                        "description": "Standard deviation of the data"
                                    },
                                    "baseline_lwr": {
                                        "description": "List of baseline lower confidence interval values. Corresponds to -95% anomaly metric.",
                                        "title": "Baseline Lower Bound",
                                        "datatype": "array"
                                    },
                                    "trendline_percent_change": {
                                        "description": "Trendline change scaled by the average of data over requested time filter",
                                        "title": "Trendline percent change"
                                    },
                                    "vals": {
                                        "description": "Timeseries data values",
                                        "title": "Values",
                                        "datatype": "array"
                                    },
                                    "cvals": {
                                        "datatype": "array",
                                        "description": "Cumulative data values",
                                        "title": "Cumulative Values"
                                    },
                                    "last": {
                                        "title": "Last",
                                        "description": "The last value in the data"
                                    },
                                    "trendline_start": {
                                        "title": "Trendline Start",
                                        "description": "Value of the first trendline data point"
                                    },
                                    "forecast_fit": {
                                        "datatype": "array",
                                        "title": "Forecast fit",
                                        "description": "An array of forecast values without periodic deviations at peak and offpeak times"
                                    },
                                    "baseline_compare": {
                                        "description": "Difference between data average and expected baseline calculated from historical data",
                                        "title": "Baseline Comparison"
                                    },
                                    "first": {
                                        "title": "First",
                                        "description": "The first value in the data"
                                    },
                                    "percentile": {
                                        "title": "Percentile",
                                        "description": "Custom percentile of the data"
                                    },
                                    "trendline_predict": {
                                        "title": "Trendline Predict",
                                        "description": "Prediction value from the trendline"
                                    },
                                    "trendline_change": {
                                        "description": "Trendline change over the requested timefilter range",
                                        "title": "Trendline change"
                                    },
                                    "baseline_upr": {
                                        "title": "Baseline Upper Bound",
                                        "description": "List of baseline upper confidence interval values. Corresponds to 95% anomaly metric.",
                                        "datatype": "array"
                                    },
                                    "avg": {
                                        "title": "Average",
                                        "description": "Average of the data"
                                    },
                                    "baseline_avg": {
                                        "description": "Average of expected baseline values calculated from historical data. Corresponds to 0% anomaly metric.",
                                        "title": "Baseline Average"
                                    },
                                    "trendline_finish": {
                                        "title": "Trendline Finish",
                                        "description": "Value of the last trendline data point"
                                    },
                                    "total": {
                                        "description": "Sum of the data",
                                        "title": "Total"
                                    },
                                    "forecast_predict": {
                                        "description": "Long term prediction value calculated from historical data",
                                        "title": "Forecast prediction"
                                    },
                                    "forecast_predict_peak": {
                                        "description": "Long term prediction value calculated from historical data at peak times",
                                        "title": "Forecast prediction peak"
                                    },
                                    "trendline_fit": {
                                        "description": "Trendline data values",
                                        "title": "Trendline fit",
                                        "datatype": "array"
                                    }
                                }
                            },
                            "stats": {
                                "values": {
                                    "forecast": {
                                        "values": {
                                            "min": {
                                                "description": "Manually set lower boundary of feasible forecast value range",
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": null,
                                                "title": "Minimum"
                                            },
                                            "data_range": {
                                                "title": "Baseline History",
                                                "default": "range = now - 180d to now",
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "description": "Timefilter for the historical data range used to calculate forecasts. Default is last 180 days.",
                                                "values": null
                                            },
                                            "predict_time": {
                                                "values": null,
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak"
                                                ],
                                                "description": "Time to use for the forecast_predict, forecast_predict_peak or forecast_predict_offpeak values (e.g. now + 10d)",
                                                "title": "Predict Time"
                                            },
                                            "max": {
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": null,
                                                "description": "Manually set upper boundary of feasible forecast value range",
                                                "title": "Maximum"
                                            },
                                            "is_cumulative": {
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_change",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "title": "Is Cumulative",
                                                "description": "whether to use cumulative forecasts",
                                                "default": false
                                            }
                                        },
                                        "description": "Forecast related input options"
                                    },
                                    "percentile": {
                                        "title": "Percentile",
                                        "values": null,
                                        "valid_formats": [
                                            "percentile"
                                        ],
                                        "description": "The value to use for the percentile format (between 0 and 100)"
                                    },
                                    "baseline": {
                                        "description": "Baseline and anomaly metric related input options",
                                        "values": {
                                            "percentile": {
                                                "description": "Baseline percentile to output",
                                                "valid_formats": [
                                                    "baseline_avg",
                                                    "baseline_compare",
                                                    "baseline_percent_compare",
                                                    "baseline"
                                                ],
                                                "default": 50,
                                                "values": null,
                                                "title": "Percentile"
                                            },
                                            "data_range": {
                                                "title": "Baseline History",
                                                "description": "Timefilter for the historical data range used to calculate baseline and anomaly metric. Default is last 180 days.",
                                                "valid_formats": [
                                                    "baseline_avg",
                                                    "baseline_compare",
                                                    "baseline_percent_compare",
                                                    "baseline",
                                                    "baseline_lwr",
                                                    "baseline_upr",
                                                    "anomaly_metric",
                                                    "anomaly_strength"
                                                ],
                                                "default": "range = now - 180d to now",
                                                "values": null
                                            },
                                            "lwr_percentile": {
                                                "title": "Lower Percentile",
                                                "description": "Baseline percentile to output for baseline lower bound",
                                                "valid_formats": [
                                                    "baseline_lwr"
                                                ],
                                                "default": 2.5,
                                                "values": null
                                            },
                                            "upr_percentile": {
                                                "valid_formats": [
                                                    "baseline_upr"
                                                ],
                                                "default": 97.5,
                                                "values": null,
                                                "description": "Baseline percentile to output for baseline upper bound",
                                                "title": "Upper Percentile"
                                            }
                                        }
                                    },
                                    "trendline": {
                                        "description": "Trendline related input options",
                                        "values": {
                                            "lwr_stddev": {
                                                "valid_formats": [
                                                    "trendline_lwr"
                                                ],
                                                "description": "The number of standard deviations to use for the trendline_lwr format",
                                                "values": null,
                                                "title": "Lower Standard Deviation"
                                            },
                                            "upr_stddev": {
                                                "title": "Upper Standard Deviation",
                                                "valid_formats": [
                                                    "trendline_upr"
                                                ],
                                                "description": "The number of standard deviations to use for the trendline_upr format",
                                                "values": null
                                            },
                                            "is_cumulative": {
                                                "title": "Is Cumulative",
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "valid_formats": [
                                                    "trendline_fit",
                                                    "trendline_predict"
                                                ],
                                                "description": "whether to use cumulative trendline"
                                            },
                                            "predict_time": {
                                                "title": "Predict Time",
                                                "valid_formats": [
                                                    "trendline_predict"
                                                ],
                                                "values": null,
                                                "description": "The time to use for the trendline_predict value"
                                            },
                                            "constrained": {
                                                "valid_formats": [
                                                    "trendline_start",
                                                    "trendline_finish",
                                                    "trendline_daily_change",
                                                    "trendline_change",
                                                    "trendline_percent_change",
                                                    "trendline_predict"
                                                ],
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "default": true,
                                                "description": "Whether to use a constrained trendline",
                                                "title": "Constrained"
                                            }
                                        },
                                        "title": "Trendline"
                                    }
                                },
                                "description": "Additional input options for certain formats"
                            },
                            "timefmt": {
                                "description": "Format a timestamp into a human readable string. Format specifier is identical to strftime(3)",
                                "values": null
                            }
                        }
                    },
                    "ping_lost3": {
                        "title": "Ping Lost 3",
                        "description": "Number of times that three ping requests in a row have been lost",
                        "polltype": "tsc",
                        "interval": 3600,
                        "datatype": "integer",
                        "options": {
                            "value_time": {
                                "description": "The timestamp for a timeseries event",
                                "values": {
                                    "none": "Do not return a timestamp",
                                    "mid": "The midpoint of the start and end timestamps",
                                    "end": "The timestamp at which the event finished",
                                    "start": "The timestamp at which the event began",
                                    "all": "An array of start, mid and end"
                                }
                            },
                            "formats": {
                                "description": "The valid data formats",
                                "values": {
                                    "median": {
                                        "description": "Median of the data",
                                        "title": "Median"
                                    },
                                    "trendline_daily_change": {
                                        "title": "Trendline daily change",
                                        "description": "Slope of the trendline (units/day)"
                                    },
                                    "anomaly_metric": {
                                        "description": "Metric from -100 to 100 indicating whether requested timeseries values are unusually large or small",
                                        "title": "Anomaly metric"
                                    },
                                    "trendline_upr": {
                                        "datatype": "array",
                                        "description": "Trendline confidence interval values (upper)",
                                        "title": "Trendline upper confidence interval"
                                    },
                                    "count": {
                                        "description": "Number of non-null data points",
                                        "title": "Count"
                                    },
                                    "baseline": {
                                        "title": "Baseline",
                                        "description": "List of expected baseline values calculated from historical data. Corresponds to 0% anomaly metric.",
                                        "datatype": "array"
                                    },
                                    "forecast_min": {
                                        "title": "Forecast minimum",
                                        "description": "Lower boundary of feasible forecast value range"
                                    },
                                    "trendline_strength": {
                                        "title": "Trendline strength",
                                        "description": "Coefficient of determination (R-squared) of the trendline"
                                    },
                                    "forecast_boundary_time": {
                                        "datatype": "time",
                                        "description": "Time forecast exceeds feasible value range if before end of timefilter range",
                                        "title": "Forecast boundary time"
                                    },
                                    "95th": {
                                        "description": "95th percentile of the data",
                                        "title": "95th percentile"
                                    },
                                    "forecast_daily_change": {
                                        "description": "The average daily change of forecast values",
                                        "title": "Forecast daily change"
                                    },
                                    "min": {
                                        "description": "Minimum data value",
                                        "title": "Minimum"
                                    },
                                    "forecast_max": {
                                        "title": "Forecast maximum",
                                        "description": "Upper boundary of feasible forecast value range"
                                    },
                                    "current": {
                                        "title": "Current",
                                        "description": "The current value"
                                    },
                                    "baseline_percent_compare": {
                                        "description": "Percentage difference between data average and expected baseline calculated from historical data",
                                        "title": "Baseline Percent Comparison"
                                    },
                                    "start_tz_offset": {
                                        "datatype": "integer",
                                        "title": "Start TZ offset",
                                        "description": "The timezone offset of the first data point"
                                    },
                                    "forecast_vals": {
                                        "datatype": "array",
                                        "title": "Forecast values",
                                        "description": "An array of forecast values with periodic deviations at peak and offpeak times"
                                    },
                                    "max": {
                                        "title": "Maximum",
                                        "description": "Maximum data value"
                                    },
                                    "trendline_lwr": {
                                        "datatype": "array",
                                        "description": "Trendline confidence interval values (lower)",
                                        "title": "Trendline lower confidence interval"
                                    },
                                    "anomaly_strength": {
                                        "description": "Metric from 0 to 100 indicating whether requested timeseries values are extreme or unusual",
                                        "title": "Anomaly strength"
                                    },
                                    "forecast_predict_offpeak": {
                                        "description": "Long term prediction value calculated from historical data at offpeak times",
                                        "title": "Forecast prediction offpeak"
                                    },
                                    "start_time": {
                                        "datatype": "time",
                                        "title": "Start time",
                                        "description": "Time of the first data point"
                                    },
                                    "stddev": {
                                        "title": "Standard deviation",
                                        "description": "Standard deviation of the data"
                                    },
                                    "baseline_lwr": {
                                        "description": "List of baseline lower confidence interval values. Corresponds to -95% anomaly metric.",
                                        "title": "Baseline Lower Bound",
                                        "datatype": "array"
                                    },
                                    "trendline_percent_change": {
                                        "description": "Trendline change scaled by the average of data over requested time filter",
                                        "title": "Trendline percent change"
                                    },
                                    "vals": {
                                        "description": "Timeseries data values",
                                        "title": "Values",
                                        "datatype": "array"
                                    },
                                    "cvals": {
                                        "datatype": "array",
                                        "description": "Cumulative data values",
                                        "title": "Cumulative Values"
                                    },
                                    "last": {
                                        "title": "Last",
                                        "description": "The last value in the data"
                                    },
                                    "trendline_start": {
                                        "title": "Trendline Start",
                                        "description": "Value of the first trendline data point"
                                    },
                                    "forecast_fit": {
                                        "datatype": "array",
                                        "title": "Forecast fit",
                                        "description": "An array of forecast values without periodic deviations at peak and offpeak times"
                                    },
                                    "baseline_compare": {
                                        "description": "Difference between data average and expected baseline calculated from historical data",
                                        "title": "Baseline Comparison"
                                    },
                                    "first": {
                                        "title": "First",
                                        "description": "The first value in the data"
                                    },
                                    "percentile": {
                                        "title": "Percentile",
                                        "description": "Custom percentile of the data"
                                    },
                                    "trendline_predict": {
                                        "title": "Trendline Predict",
                                        "description": "Prediction value from the trendline"
                                    },
                                    "trendline_change": {
                                        "description": "Trendline change over the requested timefilter range",
                                        "title": "Trendline change"
                                    },
                                    "baseline_upr": {
                                        "title": "Baseline Upper Bound",
                                        "description": "List of baseline upper confidence interval values. Corresponds to 95% anomaly metric.",
                                        "datatype": "array"
                                    },
                                    "avg": {
                                        "title": "Average",
                                        "description": "Average of the data"
                                    },
                                    "baseline_avg": {
                                        "description": "Average of expected baseline values calculated from historical data. Corresponds to 0% anomaly metric.",
                                        "title": "Baseline Average"
                                    },
                                    "trendline_finish": {
                                        "title": "Trendline Finish",
                                        "description": "Value of the last trendline data point"
                                    },
                                    "total": {
                                        "description": "Sum of the data",
                                        "title": "Total"
                                    },
                                    "forecast_predict": {
                                        "description": "Long term prediction value calculated from historical data",
                                        "title": "Forecast prediction"
                                    },
                                    "forecast_predict_peak": {
                                        "description": "Long term prediction value calculated from historical data at peak times",
                                        "title": "Forecast prediction peak"
                                    },
                                    "trendline_fit": {
                                        "description": "Trendline data values",
                                        "title": "Trendline fit",
                                        "datatype": "array"
                                    }
                                }
                            },
                            "stats": {
                                "values": {
                                    "forecast": {
                                        "values": {
                                            "min": {
                                                "description": "Manually set lower boundary of feasible forecast value range",
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": null,
                                                "title": "Minimum"
                                            },
                                            "data_range": {
                                                "title": "Baseline History",
                                                "default": "range = now - 180d to now",
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "description": "Timefilter for the historical data range used to calculate forecasts. Default is last 180 days.",
                                                "values": null
                                            },
                                            "predict_time": {
                                                "values": null,
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak"
                                                ],
                                                "description": "Time to use for the forecast_predict, forecast_predict_peak or forecast_predict_offpeak values (e.g. now + 10d)",
                                                "title": "Predict Time"
                                            },
                                            "max": {
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": null,
                                                "description": "Manually set upper boundary of feasible forecast value range",
                                                "title": "Maximum"
                                            },
                                            "is_cumulative": {
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_change",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "title": "Is Cumulative",
                                                "description": "whether to use cumulative forecasts",
                                                "default": false
                                            }
                                        },
                                        "description": "Forecast related input options"
                                    },
                                    "percentile": {
                                        "title": "Percentile",
                                        "values": null,
                                        "valid_formats": [
                                            "percentile"
                                        ],
                                        "description": "The value to use for the percentile format (between 0 and 100)"
                                    },
                                    "baseline": {
                                        "description": "Baseline and anomaly metric related input options",
                                        "values": {
                                            "percentile": {
                                                "description": "Baseline percentile to output",
                                                "valid_formats": [
                                                    "baseline_avg",
                                                    "baseline_compare",
                                                    "baseline_percent_compare",
                                                    "baseline"
                                                ],
                                                "default": 50,
                                                "values": null,
                                                "title": "Percentile"
                                            },
                                            "data_range": {
                                                "title": "Baseline History",
                                                "description": "Timefilter for the historical data range used to calculate baseline and anomaly metric. Default is last 180 days.",
                                                "valid_formats": [
                                                    "baseline_avg",
                                                    "baseline_compare",
                                                    "baseline_percent_compare",
                                                    "baseline",
                                                    "baseline_lwr",
                                                    "baseline_upr",
                                                    "anomaly_metric",
                                                    "anomaly_strength"
                                                ],
                                                "default": "range = now - 180d to now",
                                                "values": null
                                            },
                                            "lwr_percentile": {
                                                "title": "Lower Percentile",
                                                "description": "Baseline percentile to output for baseline lower bound",
                                                "valid_formats": [
                                                    "baseline_lwr"
                                                ],
                                                "default": 2.5,
                                                "values": null
                                            },
                                            "upr_percentile": {
                                                "valid_formats": [
                                                    "baseline_upr"
                                                ],
                                                "default": 97.5,
                                                "values": null,
                                                "description": "Baseline percentile to output for baseline upper bound",
                                                "title": "Upper Percentile"
                                            }
                                        }
                                    },
                                    "trendline": {
                                        "description": "Trendline related input options",
                                        "values": {
                                            "lwr_stddev": {
                                                "valid_formats": [
                                                    "trendline_lwr"
                                                ],
                                                "description": "The number of standard deviations to use for the trendline_lwr format",
                                                "values": null,
                                                "title": "Lower Standard Deviation"
                                            },
                                            "upr_stddev": {
                                                "title": "Upper Standard Deviation",
                                                "valid_formats": [
                                                    "trendline_upr"
                                                ],
                                                "description": "The number of standard deviations to use for the trendline_upr format",
                                                "values": null
                                            },
                                            "is_cumulative": {
                                                "title": "Is Cumulative",
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "valid_formats": [
                                                    "trendline_fit",
                                                    "trendline_predict"
                                                ],
                                                "description": "whether to use cumulative trendline"
                                            },
                                            "predict_time": {
                                                "title": "Predict Time",
                                                "valid_formats": [
                                                    "trendline_predict"
                                                ],
                                                "values": null,
                                                "description": "The time to use for the trendline_predict value"
                                            },
                                            "constrained": {
                                                "valid_formats": [
                                                    "trendline_start",
                                                    "trendline_finish",
                                                    "trendline_daily_change",
                                                    "trendline_change",
                                                    "trendline_percent_change",
                                                    "trendline_predict"
                                                ],
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "default": true,
                                                "description": "Whether to use a constrained trendline",
                                                "title": "Constrained"
                                            }
                                        },
                                        "title": "Trendline"
                                    }
                                },
                                "description": "Additional input options for certain formats"
                            },
                            "timefmt": {
                                "description": "Format a timestamp into a human readable string. Format specifier is identical to strftime(3)",
                                "values": null
                            }
                        }
                    },
                    "ping_lost4": {
                        "title": "Ping Lost 4",
                        "description": "Number of times that four ping requests in a row have been lost",
                        "polltype": "tsc",
                        "interval": 3600,
                        "datatype": "integer",
                        "options": {
                            "value_time": {
                                "description": "The timestamp for a timeseries event",
                                "values": {
                                    "none": "Do not return a timestamp",
                                    "mid": "The midpoint of the start and end timestamps",
                                    "end": "The timestamp at which the event finished",
                                    "start": "The timestamp at which the event began",
                                    "all": "An array of start, mid and end"
                                }
                            },
                            "formats": {
                                "description": "The valid data formats",
                                "values": {
                                    "median": {
                                        "description": "Median of the data",
                                        "title": "Median"
                                    },
                                    "trendline_daily_change": {
                                        "title": "Trendline daily change",
                                        "description": "Slope of the trendline (units/day)"
                                    },
                                    "anomaly_metric": {
                                        "description": "Metric from -100 to 100 indicating whether requested timeseries values are unusually large or small",
                                        "title": "Anomaly metric"
                                    },
                                    "trendline_upr": {
                                        "datatype": "array",
                                        "description": "Trendline confidence interval values (upper)",
                                        "title": "Trendline upper confidence interval"
                                    },
                                    "count": {
                                        "description": "Number of non-null data points",
                                        "title": "Count"
                                    },
                                    "baseline": {
                                        "title": "Baseline",
                                        "description": "List of expected baseline values calculated from historical data. Corresponds to 0% anomaly metric.",
                                        "datatype": "array"
                                    },
                                    "forecast_min": {
                                        "title": "Forecast minimum",
                                        "description": "Lower boundary of feasible forecast value range"
                                    },
                                    "trendline_strength": {
                                        "title": "Trendline strength",
                                        "description": "Coefficient of determination (R-squared) of the trendline"
                                    },
                                    "forecast_boundary_time": {
                                        "datatype": "time",
                                        "description": "Time forecast exceeds feasible value range if before end of timefilter range",
                                        "title": "Forecast boundary time"
                                    },
                                    "95th": {
                                        "description": "95th percentile of the data",
                                        "title": "95th percentile"
                                    },
                                    "forecast_daily_change": {
                                        "description": "The average daily change of forecast values",
                                        "title": "Forecast daily change"
                                    },
                                    "min": {
                                        "description": "Minimum data value",
                                        "title": "Minimum"
                                    },
                                    "forecast_max": {
                                        "title": "Forecast maximum",
                                        "description": "Upper boundary of feasible forecast value range"
                                    },
                                    "current": {
                                        "title": "Current",
                                        "description": "The current value"
                                    },
                                    "baseline_percent_compare": {
                                        "description": "Percentage difference between data average and expected baseline calculated from historical data",
                                        "title": "Baseline Percent Comparison"
                                    },
                                    "start_tz_offset": {
                                        "datatype": "integer",
                                        "title": "Start TZ offset",
                                        "description": "The timezone offset of the first data point"
                                    },
                                    "forecast_vals": {
                                        "datatype": "array",
                                        "title": "Forecast values",
                                        "description": "An array of forecast values with periodic deviations at peak and offpeak times"
                                    },
                                    "max": {
                                        "title": "Maximum",
                                        "description": "Maximum data value"
                                    },
                                    "trendline_lwr": {
                                        "datatype": "array",
                                        "description": "Trendline confidence interval values (lower)",
                                        "title": "Trendline lower confidence interval"
                                    },
                                    "anomaly_strength": {
                                        "description": "Metric from 0 to 100 indicating whether requested timeseries values are extreme or unusual",
                                        "title": "Anomaly strength"
                                    },
                                    "forecast_predict_offpeak": {
                                        "description": "Long term prediction value calculated from historical data at offpeak times",
                                        "title": "Forecast prediction offpeak"
                                    },
                                    "start_time": {
                                        "datatype": "time",
                                        "title": "Start time",
                                        "description": "Time of the first data point"
                                    },
                                    "stddev": {
                                        "title": "Standard deviation",
                                        "description": "Standard deviation of the data"
                                    },
                                    "baseline_lwr": {
                                        "description": "List of baseline lower confidence interval values. Corresponds to -95% anomaly metric.",
                                        "title": "Baseline Lower Bound",
                                        "datatype": "array"
                                    },
                                    "trendline_percent_change": {
                                        "description": "Trendline change scaled by the average of data over requested time filter",
                                        "title": "Trendline percent change"
                                    },
                                    "vals": {
                                        "description": "Timeseries data values",
                                        "title": "Values",
                                        "datatype": "array"
                                    },
                                    "cvals": {
                                        "datatype": "array",
                                        "description": "Cumulative data values",
                                        "title": "Cumulative Values"
                                    },
                                    "last": {
                                        "title": "Last",
                                        "description": "The last value in the data"
                                    },
                                    "trendline_start": {
                                        "title": "Trendline Start",
                                        "description": "Value of the first trendline data point"
                                    },
                                    "forecast_fit": {
                                        "datatype": "array",
                                        "title": "Forecast fit",
                                        "description": "An array of forecast values without periodic deviations at peak and offpeak times"
                                    },
                                    "baseline_compare": {
                                        "description": "Difference between data average and expected baseline calculated from historical data",
                                        "title": "Baseline Comparison"
                                    },
                                    "first": {
                                        "title": "First",
                                        "description": "The first value in the data"
                                    },
                                    "percentile": {
                                        "title": "Percentile",
                                        "description": "Custom percentile of the data"
                                    },
                                    "trendline_predict": {
                                        "title": "Trendline Predict",
                                        "description": "Prediction value from the trendline"
                                    },
                                    "trendline_change": {
                                        "description": "Trendline change over the requested timefilter range",
                                        "title": "Trendline change"
                                    },
                                    "baseline_upr": {
                                        "title": "Baseline Upper Bound",
                                        "description": "List of baseline upper confidence interval values. Corresponds to 95% anomaly metric.",
                                        "datatype": "array"
                                    },
                                    "avg": {
                                        "title": "Average",
                                        "description": "Average of the data"
                                    },
                                    "baseline_avg": {
                                        "description": "Average of expected baseline values calculated from historical data. Corresponds to 0% anomaly metric.",
                                        "title": "Baseline Average"
                                    },
                                    "trendline_finish": {
                                        "title": "Trendline Finish",
                                        "description": "Value of the last trendline data point"
                                    },
                                    "total": {
                                        "description": "Sum of the data",
                                        "title": "Total"
                                    },
                                    "forecast_predict": {
                                        "description": "Long term prediction value calculated from historical data",
                                        "title": "Forecast prediction"
                                    },
                                    "forecast_predict_peak": {
                                        "description": "Long term prediction value calculated from historical data at peak times",
                                        "title": "Forecast prediction peak"
                                    },
                                    "trendline_fit": {
                                        "description": "Trendline data values",
                                        "title": "Trendline fit",
                                        "datatype": "array"
                                    }
                                }
                            },
                            "stats": {
                                "values": {
                                    "forecast": {
                                        "values": {
                                            "min": {
                                                "description": "Manually set lower boundary of feasible forecast value range",
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": null,
                                                "title": "Minimum"
                                            },
                                            "data_range": {
                                                "title": "Baseline History",
                                                "default": "range = now - 180d to now",
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "description": "Timefilter for the historical data range used to calculate forecasts. Default is last 180 days.",
                                                "values": null
                                            },
                                            "predict_time": {
                                                "values": null,
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak"
                                                ],
                                                "description": "Time to use for the forecast_predict, forecast_predict_peak or forecast_predict_offpeak values (e.g. now + 10d)",
                                                "title": "Predict Time"
                                            },
                                            "max": {
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": null,
                                                "description": "Manually set upper boundary of feasible forecast value range",
                                                "title": "Maximum"
                                            },
                                            "is_cumulative": {
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_change",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "title": "Is Cumulative",
                                                "description": "whether to use cumulative forecasts",
                                                "default": false
                                            }
                                        },
                                        "description": "Forecast related input options"
                                    },
                                    "percentile": {
                                        "title": "Percentile",
                                        "values": null,
                                        "valid_formats": [
                                            "percentile"
                                        ],
                                        "description": "The value to use for the percentile format (between 0 and 100)"
                                    },
                                    "baseline": {
                                        "description": "Baseline and anomaly metric related input options",
                                        "values": {
                                            "percentile": {
                                                "description": "Baseline percentile to output",
                                                "valid_formats": [
                                                    "baseline_avg",
                                                    "baseline_compare",
                                                    "baseline_percent_compare",
                                                    "baseline"
                                                ],
                                                "default": 50,
                                                "values": null,
                                                "title": "Percentile"
                                            },
                                            "data_range": {
                                                "title": "Baseline History",
                                                "description": "Timefilter for the historical data range used to calculate baseline and anomaly metric. Default is last 180 days.",
                                                "valid_formats": [
                                                    "baseline_avg",
                                                    "baseline_compare",
                                                    "baseline_percent_compare",
                                                    "baseline",
                                                    "baseline_lwr",
                                                    "baseline_upr",
                                                    "anomaly_metric",
                                                    "anomaly_strength"
                                                ],
                                                "default": "range = now - 180d to now",
                                                "values": null
                                            },
                                            "lwr_percentile": {
                                                "title": "Lower Percentile",
                                                "description": "Baseline percentile to output for baseline lower bound",
                                                "valid_formats": [
                                                    "baseline_lwr"
                                                ],
                                                "default": 2.5,
                                                "values": null
                                            },
                                            "upr_percentile": {
                                                "valid_formats": [
                                                    "baseline_upr"
                                                ],
                                                "default": 97.5,
                                                "values": null,
                                                "description": "Baseline percentile to output for baseline upper bound",
                                                "title": "Upper Percentile"
                                            }
                                        }
                                    },
                                    "trendline": {
                                        "description": "Trendline related input options",
                                        "values": {
                                            "lwr_stddev": {
                                                "valid_formats": [
                                                    "trendline_lwr"
                                                ],
                                                "description": "The number of standard deviations to use for the trendline_lwr format",
                                                "values": null,
                                                "title": "Lower Standard Deviation"
                                            },
                                            "upr_stddev": {
                                                "title": "Upper Standard Deviation",
                                                "valid_formats": [
                                                    "trendline_upr"
                                                ],
                                                "description": "The number of standard deviations to use for the trendline_upr format",
                                                "values": null
                                            },
                                            "is_cumulative": {
                                                "title": "Is Cumulative",
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "valid_formats": [
                                                    "trendline_fit",
                                                    "trendline_predict"
                                                ],
                                                "description": "whether to use cumulative trendline"
                                            },
                                            "predict_time": {
                                                "title": "Predict Time",
                                                "valid_formats": [
                                                    "trendline_predict"
                                                ],
                                                "values": null,
                                                "description": "The time to use for the trendline_predict value"
                                            },
                                            "constrained": {
                                                "valid_formats": [
                                                    "trendline_start",
                                                    "trendline_finish",
                                                    "trendline_daily_change",
                                                    "trendline_change",
                                                    "trendline_percent_change",
                                                    "trendline_predict"
                                                ],
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "default": true,
                                                "description": "Whether to use a constrained trendline",
                                                "title": "Constrained"
                                            }
                                        },
                                        "title": "Trendline"
                                    }
                                },
                                "description": "Additional input options for certain formats"
                            },
                            "timefmt": {
                                "description": "Format a timestamp into a human readable string. Format specifier is identical to strftime(3)",
                                "values": null
                            }
                        }
                    },
                    "ping_outage": {
                        "title": "Ping Outage",
                        "description": "Number of seconds to wait before a device is considered to be down",
                        "polltype": "cfg",
                        "datatype": "integer"
                    },
                    "ping_poll": {
                        "title": "Ping Poll",
                        "description": "The ping polling status of the device",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "ping_rtt": {
                        "title": "Ping RTT",
                        "description": "The current ping state of the device",
                        "polltype": "tsg",
                        "interval": 60,
                        "units": "milliseconds",
                        "symbol": "ms",
                        "scale": "time",
                        "datatype": "integer",
                        "options": {
                            "value_time": {
                                "description": "The timestamp for a timeseries event",
                                "values": {
                                    "none": "Do not return a timestamp",
                                    "mid": "The midpoint of the start and end timestamps",
                                    "end": "The timestamp at which the event finished",
                                    "start": "The timestamp at which the event began",
                                    "all": "An array of start, mid and end"
                                }
                            },
                            "formats": {
                                "description": "The valid data formats",
                                "values": {
                                    "median": {
                                        "description": "Median of the data",
                                        "title": "Median"
                                    },
                                    "trendline_daily_change": {
                                        "title": "Trendline daily change",
                                        "description": "Slope of the trendline (units/day)"
                                    },
                                    "anomaly_metric": {
                                        "description": "Metric from -100 to 100 indicating whether requested timeseries values are unusually large or small",
                                        "title": "Anomaly metric"
                                    },
                                    "trendline_upr": {
                                        "datatype": "array",
                                        "description": "Trendline confidence interval values (upper)",
                                        "title": "Trendline upper confidence interval"
                                    },
                                    "count": {
                                        "description": "Number of non-null data points",
                                        "title": "Count"
                                    },
                                    "baseline": {
                                        "title": "Baseline",
                                        "description": "List of expected baseline values calculated from historical data. Corresponds to 0% anomaly metric.",
                                        "datatype": "array"
                                    },
                                    "forecast_min": {
                                        "title": "Forecast minimum",
                                        "description": "Lower boundary of feasible forecast value range"
                                    },
                                    "trendline_strength": {
                                        "title": "Trendline strength",
                                        "description": "Coefficient of determination (R-squared) of the trendline"
                                    },
                                    "forecast_boundary_time": {
                                        "datatype": "time",
                                        "description": "Time forecast exceeds feasible value range if before end of timefilter range",
                                        "title": "Forecast boundary time"
                                    },
                                    "95th": {
                                        "description": "95th percentile of the data",
                                        "title": "95th percentile"
                                    },
                                    "forecast_daily_change": {
                                        "description": "The average daily change of forecast values",
                                        "title": "Forecast daily change"
                                    },
                                    "min": {
                                        "description": "Minimum data value",
                                        "title": "Minimum"
                                    },
                                    "forecast_max": {
                                        "title": "Forecast maximum",
                                        "description": "Upper boundary of feasible forecast value range"
                                    },
                                    "current": {
                                        "title": "Current",
                                        "description": "The current value"
                                    },
                                    "baseline_percent_compare": {
                                        "description": "Percentage difference between data average and expected baseline calculated from historical data",
                                        "title": "Baseline Percent Comparison"
                                    },
                                    "start_tz_offset": {
                                        "datatype": "integer",
                                        "title": "Start TZ offset",
                                        "description": "The timezone offset of the first data point"
                                    },
                                    "forecast_vals": {
                                        "datatype": "array",
                                        "title": "Forecast values",
                                        "description": "An array of forecast values with periodic deviations at peak and offpeak times"
                                    },
                                    "max": {
                                        "title": "Maximum",
                                        "description": "Maximum data value"
                                    },
                                    "trendline_lwr": {
                                        "datatype": "array",
                                        "description": "Trendline confidence interval values (lower)",
                                        "title": "Trendline lower confidence interval"
                                    },
                                    "anomaly_strength": {
                                        "description": "Metric from 0 to 100 indicating whether requested timeseries values are extreme or unusual",
                                        "title": "Anomaly strength"
                                    },
                                    "forecast_predict_offpeak": {
                                        "description": "Long term prediction value calculated from historical data at offpeak times",
                                        "title": "Forecast prediction offpeak"
                                    },
                                    "start_time": {
                                        "datatype": "time",
                                        "title": "Start time",
                                        "description": "Time of the first data point"
                                    },
                                    "stddev": {
                                        "title": "Standard deviation",
                                        "description": "Standard deviation of the data"
                                    },
                                    "baseline_lwr": {
                                        "description": "List of baseline lower confidence interval values. Corresponds to -95% anomaly metric.",
                                        "title": "Baseline Lower Bound",
                                        "datatype": "array"
                                    },
                                    "trendline_percent_change": {
                                        "description": "Trendline change scaled by the average of data over requested time filter",
                                        "title": "Trendline percent change"
                                    },
                                    "vals": {
                                        "description": "Timeseries data values",
                                        "title": "Values",
                                        "datatype": "array"
                                    },
                                    "cvals": {
                                        "datatype": "array",
                                        "description": "Cumulative data values",
                                        "title": "Cumulative Values"
                                    },
                                    "last": {
                                        "title": "Last",
                                        "description": "The last value in the data"
                                    },
                                    "trendline_start": {
                                        "title": "Trendline Start",
                                        "description": "Value of the first trendline data point"
                                    },
                                    "forecast_fit": {
                                        "datatype": "array",
                                        "title": "Forecast fit",
                                        "description": "An array of forecast values without periodic deviations at peak and offpeak times"
                                    },
                                    "baseline_compare": {
                                        "description": "Difference between data average and expected baseline calculated from historical data",
                                        "title": "Baseline Comparison"
                                    },
                                    "first": {
                                        "title": "First",
                                        "description": "The first value in the data"
                                    },
                                    "percentile": {
                                        "title": "Percentile",
                                        "description": "Custom percentile of the data"
                                    },
                                    "trendline_predict": {
                                        "title": "Trendline Predict",
                                        "description": "Prediction value from the trendline"
                                    },
                                    "trendline_change": {
                                        "description": "Trendline change over the requested timefilter range",
                                        "title": "Trendline change"
                                    },
                                    "baseline_upr": {
                                        "title": "Baseline Upper Bound",
                                        "description": "List of baseline upper confidence interval values. Corresponds to 95% anomaly metric.",
                                        "datatype": "array"
                                    },
                                    "avg": {
                                        "title": "Average",
                                        "description": "Average of the data"
                                    },
                                    "baseline_avg": {
                                        "description": "Average of expected baseline values calculated from historical data. Corresponds to 0% anomaly metric.",
                                        "title": "Baseline Average"
                                    },
                                    "trendline_finish": {
                                        "title": "Trendline Finish",
                                        "description": "Value of the last trendline data point"
                                    },
                                    "total": {
                                        "description": "Sum of the data",
                                        "title": "Total"
                                    },
                                    "forecast_predict": {
                                        "description": "Long term prediction value calculated from historical data",
                                        "title": "Forecast prediction"
                                    },
                                    "forecast_predict_peak": {
                                        "description": "Long term prediction value calculated from historical data at peak times",
                                        "title": "Forecast prediction peak"
                                    },
                                    "trendline_fit": {
                                        "description": "Trendline data values",
                                        "title": "Trendline fit",
                                        "datatype": "array"
                                    }
                                }
                            },
                            "stats": {
                                "values": {
                                    "forecast": {
                                        "values": {
                                            "min": {
                                                "description": "Manually set lower boundary of feasible forecast value range",
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": null,
                                                "title": "Minimum"
                                            },
                                            "data_range": {
                                                "title": "Baseline History",
                                                "default": "range = now - 180d to now",
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "description": "Timefilter for the historical data range used to calculate forecasts. Default is last 180 days.",
                                                "values": null
                                            },
                                            "predict_time": {
                                                "values": null,
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak"
                                                ],
                                                "description": "Time to use for the forecast_predict, forecast_predict_peak or forecast_predict_offpeak values (e.g. now + 10d)",
                                                "title": "Predict Time"
                                            },
                                            "max": {
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": null,
                                                "description": "Manually set upper boundary of feasible forecast value range",
                                                "title": "Maximum"
                                            },
                                            "is_cumulative": {
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_change",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "description": "Whether to return the sum of forecast values",
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "title": "Is Cumulative"
                                            }
                                        },
                                        "description": "Forecast related input options"
                                    },
                                    "percentile": {
                                        "title": "Percentile",
                                        "values": null,
                                        "valid_formats": [
                                            "percentile"
                                        ],
                                        "description": "The value to use for the percentile format (between 0 and 100)"
                                    },
                                    "baseline": {
                                        "description": "Baseline and anomaly metric related input options",
                                        "values": {
                                            "percentile": {
                                                "description": "Baseline percentile to output",
                                                "valid_formats": [
                                                    "baseline_avg",
                                                    "baseline_compare",
                                                    "baseline_percent_compare",
                                                    "baseline"
                                                ],
                                                "default": 50,
                                                "values": null,
                                                "title": "Percentile"
                                            },
                                            "data_range": {
                                                "title": "Baseline History",
                                                "description": "Timefilter for the historical data range used to calculate baseline and anomaly metric. Default is last 180 days.",
                                                "valid_formats": [
                                                    "baseline_avg",
                                                    "baseline_compare",
                                                    "baseline_percent_compare",
                                                    "baseline",
                                                    "baseline_lwr",
                                                    "baseline_upr",
                                                    "anomaly_metric",
                                                    "anomaly_strength"
                                                ],
                                                "default": "range = now - 180d to now",
                                                "values": null
                                            },
                                            "lwr_percentile": {
                                                "title": "Lower Percentile",
                                                "description": "Baseline percentile to output for baseline lower bound",
                                                "valid_formats": [
                                                    "baseline_lwr"
                                                ],
                                                "default": 2.5,
                                                "values": null
                                            },
                                            "upr_percentile": {
                                                "valid_formats": [
                                                    "baseline_upr"
                                                ],
                                                "default": 97.5,
                                                "values": null,
                                                "description": "Baseline percentile to output for baseline upper bound",
                                                "title": "Upper Percentile"
                                            }
                                        }
                                    },
                                    "trendline": {
                                        "description": "Trendline related input options",
                                        "values": {
                                            "lwr_stddev": {
                                                "valid_formats": [
                                                    "trendline_lwr"
                                                ],
                                                "description": "The number of standard deviations to use for the trendline_lwr format",
                                                "values": null,
                                                "title": "Lower Standard Deviation"
                                            },
                                            "upr_stddev": {
                                                "title": "Upper Standard Deviation",
                                                "valid_formats": [
                                                    "trendline_upr"
                                                ],
                                                "description": "The number of standard deviations to use for the trendline_upr format",
                                                "values": null
                                            },
                                            "is_cumulative": {
                                                "description": "Whether to fit a trendline to the sum of the data values",
                                                "valid_formats": [
                                                    "trendline_fit",
                                                    "trendline_predict"
                                                ],
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "title": "Is Cumulative"
                                            },
                                            "predict_time": {
                                                "title": "Predict Time",
                                                "valid_formats": [
                                                    "trendline_predict"
                                                ],
                                                "values": null,
                                                "description": "The time to use for the trendline_predict value"
                                            },
                                            "constrained": {
                                                "valid_formats": [
                                                    "trendline_start",
                                                    "trendline_finish",
                                                    "trendline_daily_change",
                                                    "trendline_change",
                                                    "trendline_percent_change",
                                                    "trendline_predict"
                                                ],
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "default": true,
                                                "description": "Whether to use a constrained trendline",
                                                "title": "Constrained"
                                            }
                                        },
                                        "title": "Trendline"
                                    }
                                },
                                "description": "Additional input options for certain formats"
                            },
                            "timefmt": {
                                "description": "Format a timestamp into a human readable string. Format specifier is identical to strftime(3)",
                                "values": null
                            }
                        }
                    },
                    "ping_rtt_ms": {
                        "title": "Ping RTT(High Precision)",
                        "description": "The current ping state of the device in ms to 3 decimal places",
                        "polltype": "tsg",
                        "interval": 60,
                        "units": "milliseconds",
                        "symbol": "ms",
                        "scale": "time",
                        "datatype": "float",
                        "options": {
                            "value_time": {
                                "description": "The timestamp for a timeseries event",
                                "values": {
                                    "none": "Do not return a timestamp",
                                    "mid": "The midpoint of the start and end timestamps",
                                    "end": "The timestamp at which the event finished",
                                    "start": "The timestamp at which the event began",
                                    "all": "An array of start, mid and end"
                                }
                            },
                            "formats": {
                                "description": "The valid data formats",
                                "values": {
                                    "median": {
                                        "description": "Median of the data",
                                        "title": "Median"
                                    },
                                    "trendline_daily_change": {
                                        "title": "Trendline daily change",
                                        "description": "Slope of the trendline (units/day)"
                                    },
                                    "anomaly_metric": {
                                        "description": "Metric from -100 to 100 indicating whether requested timeseries values are unusually large or small",
                                        "title": "Anomaly metric"
                                    },
                                    "trendline_upr": {
                                        "datatype": "array",
                                        "description": "Trendline confidence interval values (upper)",
                                        "title": "Trendline upper confidence interval"
                                    },
                                    "count": {
                                        "description": "Number of non-null data points",
                                        "title": "Count"
                                    },
                                    "baseline": {
                                        "title": "Baseline",
                                        "description": "List of expected baseline values calculated from historical data. Corresponds to 0% anomaly metric.",
                                        "datatype": "array"
                                    },
                                    "forecast_min": {
                                        "title": "Forecast minimum",
                                        "description": "Lower boundary of feasible forecast value range"
                                    },
                                    "trendline_strength": {
                                        "title": "Trendline strength",
                                        "description": "Coefficient of determination (R-squared) of the trendline"
                                    },
                                    "forecast_boundary_time": {
                                        "datatype": "time",
                                        "description": "Time forecast exceeds feasible value range if before end of timefilter range",
                                        "title": "Forecast boundary time"
                                    },
                                    "95th": {
                                        "description": "95th percentile of the data",
                                        "title": "95th percentile"
                                    },
                                    "forecast_daily_change": {
                                        "description": "The average daily change of forecast values",
                                        "title": "Forecast daily change"
                                    },
                                    "min": {
                                        "description": "Minimum data value",
                                        "title": "Minimum"
                                    },
                                    "forecast_max": {
                                        "title": "Forecast maximum",
                                        "description": "Upper boundary of feasible forecast value range"
                                    },
                                    "current": {
                                        "title": "Current",
                                        "description": "The current value"
                                    },
                                    "baseline_percent_compare": {
                                        "description": "Percentage difference between data average and expected baseline calculated from historical data",
                                        "title": "Baseline Percent Comparison"
                                    },
                                    "start_tz_offset": {
                                        "datatype": "integer",
                                        "title": "Start TZ offset",
                                        "description": "The timezone offset of the first data point"
                                    },
                                    "forecast_vals": {
                                        "datatype": "array",
                                        "title": "Forecast values",
                                        "description": "An array of forecast values with periodic deviations at peak and offpeak times"
                                    },
                                    "max": {
                                        "title": "Maximum",
                                        "description": "Maximum data value"
                                    },
                                    "trendline_lwr": {
                                        "datatype": "array",
                                        "description": "Trendline confidence interval values (lower)",
                                        "title": "Trendline lower confidence interval"
                                    },
                                    "anomaly_strength": {
                                        "description": "Metric from 0 to 100 indicating whether requested timeseries values are extreme or unusual",
                                        "title": "Anomaly strength"
                                    },
                                    "forecast_predict_offpeak": {
                                        "description": "Long term prediction value calculated from historical data at offpeak times",
                                        "title": "Forecast prediction offpeak"
                                    },
                                    "start_time": {
                                        "datatype": "time",
                                        "title": "Start time",
                                        "description": "Time of the first data point"
                                    },
                                    "stddev": {
                                        "title": "Standard deviation",
                                        "description": "Standard deviation of the data"
                                    },
                                    "baseline_lwr": {
                                        "description": "List of baseline lower confidence interval values. Corresponds to -95% anomaly metric.",
                                        "title": "Baseline Lower Bound",
                                        "datatype": "array"
                                    },
                                    "trendline_percent_change": {
                                        "description": "Trendline change scaled by the average of data over requested time filter",
                                        "title": "Trendline percent change"
                                    },
                                    "vals": {
                                        "description": "Timeseries data values",
                                        "title": "Values",
                                        "datatype": "array"
                                    },
                                    "cvals": {
                                        "datatype": "array",
                                        "description": "Cumulative data values",
                                        "title": "Cumulative Values"
                                    },
                                    "last": {
                                        "title": "Last",
                                        "description": "The last value in the data"
                                    },
                                    "trendline_start": {
                                        "title": "Trendline Start",
                                        "description": "Value of the first trendline data point"
                                    },
                                    "forecast_fit": {
                                        "datatype": "array",
                                        "title": "Forecast fit",
                                        "description": "An array of forecast values without periodic deviations at peak and offpeak times"
                                    },
                                    "baseline_compare": {
                                        "description": "Difference between data average and expected baseline calculated from historical data",
                                        "title": "Baseline Comparison"
                                    },
                                    "first": {
                                        "title": "First",
                                        "description": "The first value in the data"
                                    },
                                    "percentile": {
                                        "title": "Percentile",
                                        "description": "Custom percentile of the data"
                                    },
                                    "trendline_predict": {
                                        "title": "Trendline Predict",
                                        "description": "Prediction value from the trendline"
                                    },
                                    "trendline_change": {
                                        "description": "Trendline change over the requested timefilter range",
                                        "title": "Trendline change"
                                    },
                                    "baseline_upr": {
                                        "title": "Baseline Upper Bound",
                                        "description": "List of baseline upper confidence interval values. Corresponds to 95% anomaly metric.",
                                        "datatype": "array"
                                    },
                                    "avg": {
                                        "title": "Average",
                                        "description": "Average of the data"
                                    },
                                    "baseline_avg": {
                                        "description": "Average of expected baseline values calculated from historical data. Corresponds to 0% anomaly metric.",
                                        "title": "Baseline Average"
                                    },
                                    "trendline_finish": {
                                        "title": "Trendline Finish",
                                        "description": "Value of the last trendline data point"
                                    },
                                    "total": {
                                        "description": "Sum of the data",
                                        "title": "Total"
                                    },
                                    "forecast_predict": {
                                        "description": "Long term prediction value calculated from historical data",
                                        "title": "Forecast prediction"
                                    },
                                    "forecast_predict_peak": {
                                        "description": "Long term prediction value calculated from historical data at peak times",
                                        "title": "Forecast prediction peak"
                                    },
                                    "trendline_fit": {
                                        "description": "Trendline data values",
                                        "title": "Trendline fit",
                                        "datatype": "array"
                                    }
                                }
                            },
                            "stats": {
                                "values": {
                                    "forecast": {
                                        "values": {
                                            "min": {
                                                "description": "Manually set lower boundary of feasible forecast value range",
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": null,
                                                "title": "Minimum"
                                            },
                                            "data_range": {
                                                "title": "Baseline History",
                                                "default": "range = now - 180d to now",
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "description": "Timefilter for the historical data range used to calculate forecasts. Default is last 180 days.",
                                                "values": null
                                            },
                                            "predict_time": {
                                                "values": null,
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak"
                                                ],
                                                "description": "Time to use for the forecast_predict, forecast_predict_peak or forecast_predict_offpeak values (e.g. now + 10d)",
                                                "title": "Predict Time"
                                            },
                                            "max": {
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_slope",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "values": null,
                                                "description": "Manually set upper boundary of feasible forecast value range",
                                                "title": "Maximum"
                                            },
                                            "is_cumulative": {
                                                "valid_formats": [
                                                    "forecast_predict",
                                                    "forecast_predict_peak",
                                                    "forecast_predict_offpeak",
                                                    "forecast_min",
                                                    "forecast_max",
                                                    "forecast_boundary_time",
                                                    "forecast_daily_change",
                                                    "forecast_fit",
                                                    "forecast_vals"
                                                ],
                                                "description": "Whether to return the sum of forecast values",
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "title": "Is Cumulative"
                                            }
                                        },
                                        "description": "Forecast related input options"
                                    },
                                    "percentile": {
                                        "title": "Percentile",
                                        "values": null,
                                        "valid_formats": [
                                            "percentile"
                                        ],
                                        "description": "The value to use for the percentile format (between 0 and 100)"
                                    },
                                    "baseline": {
                                        "description": "Baseline and anomaly metric related input options",
                                        "values": {
                                            "percentile": {
                                                "description": "Baseline percentile to output",
                                                "valid_formats": [
                                                    "baseline_avg",
                                                    "baseline_compare",
                                                    "baseline_percent_compare",
                                                    "baseline"
                                                ],
                                                "default": 50,
                                                "values": null,
                                                "title": "Percentile"
                                            },
                                            "data_range": {
                                                "title": "Baseline History",
                                                "description": "Timefilter for the historical data range used to calculate baseline and anomaly metric. Default is last 180 days.",
                                                "valid_formats": [
                                                    "baseline_avg",
                                                    "baseline_compare",
                                                    "baseline_percent_compare",
                                                    "baseline",
                                                    "baseline_lwr",
                                                    "baseline_upr",
                                                    "anomaly_metric",
                                                    "anomaly_strength"
                                                ],
                                                "default": "range = now - 180d to now",
                                                "values": null
                                            },
                                            "lwr_percentile": {
                                                "title": "Lower Percentile",
                                                "description": "Baseline percentile to output for baseline lower bound",
                                                "valid_formats": [
                                                    "baseline_lwr"
                                                ],
                                                "default": 2.5,
                                                "values": null
                                            },
                                            "upr_percentile": {
                                                "valid_formats": [
                                                    "baseline_upr"
                                                ],
                                                "default": 97.5,
                                                "values": null,
                                                "description": "Baseline percentile to output for baseline upper bound",
                                                "title": "Upper Percentile"
                                            }
                                        }
                                    },
                                    "trendline": {
                                        "description": "Trendline related input options",
                                        "values": {
                                            "lwr_stddev": {
                                                "valid_formats": [
                                                    "trendline_lwr"
                                                ],
                                                "description": "The number of standard deviations to use for the trendline_lwr format",
                                                "values": null,
                                                "title": "Lower Standard Deviation"
                                            },
                                            "upr_stddev": {
                                                "title": "Upper Standard Deviation",
                                                "valid_formats": [
                                                    "trendline_upr"
                                                ],
                                                "description": "The number of standard deviations to use for the trendline_upr format",
                                                "values": null
                                            },
                                            "is_cumulative": {
                                                "description": "Whether to fit a trendline to the sum of the data values",
                                                "valid_formats": [
                                                    "trendline_fit",
                                                    "trendline_predict"
                                                ],
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "title": "Is Cumulative"
                                            },
                                            "predict_time": {
                                                "title": "Predict Time",
                                                "valid_formats": [
                                                    "trendline_predict"
                                                ],
                                                "values": null,
                                                "description": "The time to use for the trendline_predict value"
                                            },
                                            "constrained": {
                                                "valid_formats": [
                                                    "trendline_start",
                                                    "trendline_finish",
                                                    "trendline_daily_change",
                                                    "trendline_change",
                                                    "trendline_percent_change",
                                                    "trendline_predict"
                                                ],
                                                "values": [
                                                    true,
                                                    false
                                                ],
                                                "default": true,
                                                "description": "Whether to use a constrained trendline",
                                                "title": "Constrained"
                                            }
                                        },
                                        "title": "Trendline"
                                    }
                                },
                                "description": "Additional input options for certain formats"
                            },
                            "timefmt": {
                                "description": "Format a timestamp into a human readable string. Format specifier is identical to strftime(3)",
                                "values": null
                            }
                        }
                    },
                    "ping_state": {
                        "title": "Ping State",
                        "description": "The current ping state of the device",
                        "polltype": "evt",
                        "interval": 60,
                        "datatype": "string",
                        "enum": {
                            "1": {
                                "label": "up",
                                "description": "Device is up"
                            },
                            "2": {
                                "label": "down",
                                "description": "Device is down"
                            }
                        },
                        "options": {
                            "formats": {
                                "description": "The valid data formats",
                                "values": {
                                    "avl_outTransitions": {
                                        "title": "Transitions out of states",
                                        "datatype": "integer",
                                        "description": "The number of transitions from a state that wasn't request to a requested state"
                                    },
                                    "avl_inTransitions": {
                                        "description": "The number of transitions from one of the requested states to a state not requested",
                                        "datatype": "integer",
                                        "title": "Transitions into states"
                                    },
                                    "avl_outTime": {
                                        "title": "Time not in states",
                                        "description": "The time the event has not been in any of the requested states",
                                        "datatype": "integer"
                                    },
                                    "avl_inTime": {
                                        "title": "Time in states",
                                        "datatype": "float",
                                        "description": "The time the event has been in any of the requested states"
                                    },
                                    "state_inTime": {
                                        "description": "The number of seconds that the current state has been active",
                                        "datatype": "integer",
                                        "title": "Time in current state"
                                    },
                                    "avl_outPercent": {
                                        "title": "Percent not in states",
                                        "description": "The percent of time the event has not been in any of the states",
                                        "datatype": "float"
                                    },
                                    "avl_inPercent": {
                                        "datatype": "float",
                                        "description": "The percent of time the event has been in any of the requested states",
                                        "title": "Percent in states"
                                    },
                                    "state_id": {
                                        "description": "The current state identifier of the event",
                                        "datatype": "integer",
                                        "title": "State ID"
                                    },
                                    "state_delta": {
                                        "title": "Time in previous state",
                                        "description": "The number of seconds to the previous record",
                                        "datatype": "integer"
                                    },
                                    "avl_totalTransitions": {
                                        "title": "Total transitions",
                                        "datatype": "integer",
                                        "description": "The total number of transition between all of the states"
                                    },
                                    "state_time": {
                                        "datatype": "time",
                                        "description": "The time of the last transition",
                                        "title": "Time of last transition"
                                    },
                                    "poll": {
                                        "title": "Poll",
                                        "description": "Whether polling is enabled for the event",
                                        "datatype": "string"
                                    },
                                    "state": {
                                        "datatype": "string",
                                        "description": "The current state of the event",
                                        "title": "State"
                                    }
                                }
                            },
                            "states": {
                                "values": null,
                                "description": "Array of state names to use for the calculations"
                            }
                        }
                    },
                    "priv_method": {
                        "title": "SNMPv3 Privacy Method",
                        "description": "Privacy method for SNMPv3 devices",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "priv_pass": {
                        "title": "SNMPv3 Privacy Password",
                        "description": "Privacy password for SNMPv3 devices",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "retired": {
                        "title": "Retired",
                        "description": "The device has been Retired",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "snmpEngineID": {
                        "title": "SNMP Engine ID",
                        "description": "An SNMP engine's administratively-unique identifier",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "snmp_maxoid": {
                        "title": "SNMP Max OID",
                        "description": "Maximum number of oids to poll in a single request",
                        "polltype": "cfg",
                        "datatype": "integer"
                    },
                    "snmp_poll": {
                        "title": "SNMP Poll",
                        "description": "The SNMP polling status of the device",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "snmp_version": {
                        "title": "SNMP Version",
                        "description": "The SNMP version of the device",
                        "polltype": "cfg",
                        "datatype": "integer"
                    },
                    "sysContact": {
                        "title": "Contact",
                        "description": "The textual identification of the contact person for the entity",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "sysDescr": {
                        "title": "System Description",
                        "description": "A textual description of the entity",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "sysLocation": {
                        "title": "Location",
                        "description": "The physical location of the entity",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "sysName": {
                        "title": "System Name",
                        "description": "An administratively-assigned name for the entity",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "sysObjectID": {
                        "title": "Object ID",
                        "description": "The vendor's authoritative identification of the network management subsystem contained in the entity",
                        "polltype": "cfg",
                        "datatype": "string"
                    },
                    "sysServices": {
                        "title": "Services",
                        "description": "A value which indicates the set of services that the entity may potentially offer",
                        "polltype": "cfg",
                        "datatype": "integer"
                    },
                    "vendor": {
                        "title": "Vendor",
                        "description": "The vendor name for the device",
                        "polltype": "cfg",
                        "datatype": "string"
                    }
                },
                "commands": {
                    "add": {
                        "valid_fields": null,
                        "valid_data": {
                            "ipaddress": {
                                "required": true
                            },
                            "community": {
                                "required": false
                            },
                            "hostname": {
                                "required": false
                            },
                            "snmp_version": {
                                "required": false
                            },
                            "auth_method": {
                                "required": false
                            },
                            "auth_user": {
                                "required": false
                            },
                            "auth_pass": {
                                "required": false
                            },
                            "priv_method": {
                                "required": false
                            },
                            "priv_pass": {
                                "required": false
                            },
                            "context": {
                                "required": false
                            },
                            "snmp_poll": {
                                "required": false
                            },
                            "ping_poll": {
                                "required": false
                            },
                            "longitude": {
                                "required": false
                            },
                            "latitude": {
                                "required": false
                            }
                        }
                    },
                    "update": {
                        "valid_fields": {
                            "id": {
                                "required": false
                            },
                            "name": {
                                "required": false
                            },
                            "deviceid": {
                                "required": false
                            },
                            "idx": {
                                "required": false
                            },
                            "table": {
                                "required": false
                            },
                            "poll": {
                                "required": false
                            },
                            "auth_method": {
                                "required": false
                            },
                            "auth_pass": {
                                "required": false
                            },
                            "auth_user": {
                                "required": false
                            },
                            "community": {
                                "required": false
                            },
                            "context": {
                                "required": false
                            },
                            "custom_data_details": {
                                "required": false
                            },
                            "discover_getNext": {
                                "required": false
                            },
                            "discover_minimal": {
                                "required": false
                            },
                            "discover_snmpv1": {
                                "required": false
                            },
                            "hostname": {
                                "required": false
                            },
                            "ipaddress": {
                                "required": false
                            },
                            "latitude": {
                                "required": false
                            },
                            "longitude": {
                                "required": false
                            },
                            "manual_name": {
                                "required": false
                            },
                            "memorySize": {
                                "required": false
                            },
                            "mis": {
                                "required": false
                            },
                            "ping_dup": {
                                "required": false
                            },
                            "ping_lost1": {
                                "required": false
                            },
                            "ping_lost2": {
                                "required": false
                            },
                            "ping_lost3": {
                                "required": false
                            },
                            "ping_lost4": {
                                "required": false
                            },
                            "ping_outage": {
                                "required": false
                            },
                            "ping_poll": {
                                "required": false
                            },
                            "ping_rtt": {
                                "required": false
                            },
                            "ping_rtt_ms": {
                                "required": false
                            },
                            "ping_state": {
                                "required": false
                            },
                            "priv_method": {
                                "required": false
                            },
                            "priv_pass": {
                                "required": false
                            },
                            "retired": {
                                "required": false
                            },
                            "snmpEngineID": {
                                "required": false
                            },
                            "snmp_maxoid": {
                                "required": false
                            },
                            "snmp_poll": {
                                "required": false
                            },
                            "snmp_version": {
                                "required": false
                            },
                            "sysContact": {
                                "required": false
                            },
                            "sysDescr": {
                                "required": false
                            },
                            "sysLocation": {
                                "required": false
                            },
                            "sysName": {
                                "required": false
                            },
                            "sysObjectID": {
                                "required": false
                            },
                            "sysServices": {
                                "required": false
                            },
                            "vendor": {
                                "required": false
                            }
                        },
                        "valid_data": {
                            "poll": {
                                "required": false
                            },
                            "auth_method": {
                                "required": false
                            },
                            "auth_pass": {
                                "required": false
                            },
                            "auth_user": {
                                "required": false
                            },
                            "community": {
                                "required": false
                            },
                            "context": {
                                "required": false
                            },
                            "custom_data_details": {
                                "required": false
                            },
                            "discover_getNext": {
                                "required": false
                            },
                            "discover_minimal": {
                                "required": false
                            },
                            "discover_snmpv1": {
                                "required": false
                            },
                            "hostname": {
                                "required": false
                            },
                            "ipaddress": {
                                "required": false
                            },
                            "latitude": {
                                "required": false
                            },
                            "longitude": {
                                "required": false
                            },
                            "manual_name": {
                                "required": false
                            },
                            "mis": {
                                "required": false
                            },
                            "ping_outage": {
                                "required": false
                            },
                            "ping_poll": {
                                "required": false
                            },
                            "ping_state": {
                                "required": false
                            },
                            "priv_method": {
                                "required": false
                            },
                            "priv_pass": {
                                "required": false
                            },
                            "snmpEngineID": {
                                "required": false
                            },
                            "snmp_maxoid": {
                                "required": false
                            },
                            "snmp_poll": {
                                "required": false
                            },
                            "snmp_version": {
                                "required": false
                            },
                            "sysContact": {
                                "required": false
                            },
                            "sysDescr": {
                                "required": false
                            },
                            "sysLocation": {
                                "required": false
                            },
                            "sysName": {
                                "required": false
                            },
                            "sysObjectID": {
                                "required": false
                            },
                            "sysServices": {
                                "required": false
                            }
                        }
                    },
                    "delete": {
                        "valid_fields": {
                            "id": {
                                "required": false
                            },
                            "name": {
                                "required": false
                            },
                            "deviceid": {
                                "required": false
                            },
                            "idx": {
                                "required": false
                            },
                            "table": {
                                "required": false
                            },
                            "poll": {
                                "required": false
                            },
                            "auth_method": {
                                "required": false
                            },
                            "auth_pass": {
                                "required": false
                            },
                            "auth_user": {
                                "required": false
                            },
                            "community": {
                                "required": false
                            },
                            "context": {
                                "required": false
                            },
                            "custom_data_details": {
                                "required": false
                            },
                            "discover_getNext": {
                                "required": false
                            },
                            "discover_minimal": {
                                "required": false
                            },
                            "discover_snmpv1": {
                                "required": false
                            },
                            "hostname": {
                                "required": false
                            },
                            "ipaddress": {
                                "required": false
                            },
                            "latitude": {
                                "required": false
                            },
                            "longitude": {
                                "required": false
                            },
                            "manual_name": {
                                "required": false
                            },
                            "memorySize": {
                                "required": false
                            },
                            "mis": {
                                "required": false
                            },
                            "ping_dup": {
                                "required": false
                            },
                            "ping_lost1": {
                                "required": false
                            },
                            "ping_lost2": {
                                "required": false
                            },
                            "ping_lost3": {
                                "required": false
                            },
                            "ping_lost4": {
                                "required": false
                            },
                            "ping_outage": {
                                "required": false
                            },
                            "ping_poll": {
                                "required": false
                            },
                            "ping_rtt": {
                                "required": false
                            },
                            "ping_rtt_ms": {
                                "required": false
                            },
                            "ping_state": {
                                "required": false
                            },
                            "priv_method": {
                                "required": false
                            },
                            "priv_pass": {
                                "required": false
                            },
                            "retired": {
                                "required": false
                            },
                            "snmpEngineID": {
                                "required": false
                            },
                            "snmp_maxoid": {
                                "required": false
                            },
                            "snmp_poll": {
                                "required": false
                            },
                            "snmp_version": {
                                "required": false
                            },
                            "sysContact": {
                                "required": false
                            },
                            "sysDescr": {
                                "required": false
                            },
                            "sysLocation": {
                                "required": false
                            },
                            "sysName": {
                                "required": false
                            },
                            "sysObjectID": {
                                "required": false
                            },
                            "sysServices": {
                                "required": false
                            },
                            "vendor": {
                                "required": false
                            }
                        },
                        "valid_data": null
                    },
                    "get": {
                        "valid_fields": {
                            "id": {
                                "required": false
                            },
                            "name": {
                                "required": false
                            },
                            "deviceid": {
                                "required": false
                            },
                            "idx": {
                                "required": false
                            },
                            "table": {
                                "required": false
                            },
                            "poll": {
                                "required": false
                            },
                            "auth_method": {
                                "required": false
                            },
                            "auth_pass": {
                                "required": false
                            },
                            "auth_user": {
                                "required": false
                            },
                            "community": {
                                "required": false
                            },
                            "context": {
                                "required": false
                            },
                            "custom_data_details": {
                                "required": false
                            },
                            "discover_getNext": {
                                "required": false
                            },
                            "discover_minimal": {
                                "required": false
                            },
                            "discover_snmpv1": {
                                "required": false
                            },
                            "hostname": {
                                "required": false
                            },
                            "ipaddress": {
                                "required": false
                            },
                            "latitude": {
                                "required": false
                            },
                            "longitude": {
                                "required": false
                            },
                            "manual_name": {
                                "required": false
                            },
                            "memorySize": {
                                "required": false
                            },
                            "mis": {
                                "required": false
                            },
                            "ping_dup": {
                                "required": false
                            },
                            "ping_lost1": {
                                "required": false
                            },
                            "ping_lost2": {
                                "required": false
                            },
                            "ping_lost3": {
                                "required": false
                            },
                            "ping_lost4": {
                                "required": false
                            },
                            "ping_outage": {
                                "required": false
                            },
                            "ping_poll": {
                                "required": false
                            },
                            "ping_rtt": {
                                "required": false
                            },
                            "ping_rtt_ms": {
                                "required": false
                            },
                            "ping_state": {
                                "required": false
                            },
                            "priv_method": {
                                "required": false
                            },
                            "priv_pass": {
                                "required": false
                            },
                            "retired": {
                                "required": false
                            },
                            "snmpEngineID": {
                                "required": false
                            },
                            "snmp_maxoid": {
                                "required": false
                            },
                            "snmp_poll": {
                                "required": false
                            },
                            "snmp_version": {
                                "required": false
                            },
                            "sysContact": {
                                "required": false
                            },
                            "sysDescr": {
                                "required": false
                            },
                            "sysLocation": {
                                "required": false
                            },
                            "sysName": {
                                "required": false
                            },
                            "sysObjectID": {
                                "required": false
                            },
                            "sysServices": {
                                "required": false
                            },
                            "vendor": {
                                "required": false
                            }
                        },
                        "valid_data": null
                    },
                    "describe": {
                        "valid_fields": null,
                        "valid_data": null
                    }
                },
                "info": {
                    "tags": [],
                    "licenced": false,
                    "vendor": "Standard",
                    "category": "Device",
                    "inherited_by": [
                        "cdt_device_apic",
                        "cdt_device_freebsd"
                    ],
                    "inherits": null,
                    "allow_grouping": 1,
                    "allow_reporting": 1,
                    "allow_discovery": 0,
                    "poller": "snmp"
                },
                "allow_formula_fields": true,
                "links": {
                    "macLink": {
                        "title": "Link to MAC",
                        "object": "mac",
                        "default": 1
                    }
                },
                "global_field_options": {
                    "aggregation_format": {
                        "description": "Aggregation formats to apply when group_by option is provided",
                        "values": {
                            "first": {
                                "title": "First",
                                "description": "First value in the group (default)"
                            },
                            "last": {
                                "title": "Last",
                                "description": "Last value in the group"
                            },
                            "avg": {
                                "title": "Average",
                                "description": "Average of the values in the group"
                            },
                            "count": {
                                "title": "Count",
                                "description": "Number on non-null values in the group"
                            },
                            "count_all": {
                                "title": "Count (include NULL)",
                                "description": "Number of values in the group (including null values)"
                            },
                            "count_unique": {
                                "title": "Unique count",
                                "description": "Number of unique non-null values in the group"
                            },
                            "count_unique_all": {
                                "title": "Unique count (include NULL)",
                                "description": "Number of unique values in the group (including null values)"
                            },
                            "cat": {
                                "title": "Concatenate",
                                "description": "Concatenation of the values in the group"
                            },
                            "list": {
                                "title": "List",
                                "description": "Comma separated concatenation of the values in the group"
                            },
                            "list_unique": {
                                "title": "Unique List",
                                "description": "Comma separated concatenation of the unique values in the group"
                            },
                            "min": {
                                "title": "Minimum",
                                "description": "Minimum of the values in the group"
                            },
                            "max": {
                                "title": "Maximum",
                                "description": "Maximum of the values in the group"
                            },
                            "sum": {
                                "title": "Sum",
                                "description": "Sum of all values in the group (null if no valid values)"
                            },
                            "total": {
                                "title": "Total",
                                "description": "Sum of all values in the group (0 if no valid values)"
                            },
                            "median": {
                                "title": "Median",
                                "description": "Median of the values in the group"
                            },
                            "95th": {
                                "title": "95th percentile",
                                "description": "95th percentile of the values in the group"
                            },
                            "stddev": {
                                "title": "Standard deviation",
                                "description": "Standard deviation of the values in the group"
                            }
                        }
                    }
                }
            }
        ]
    },
    "links": [
        {
            "link": "/api/v2.1/cdt_device/describe",
            "rel": "self"
        },
        {
            "link": "/api/v2.1",
            "rel": "base"
        },
        {
            "link": "/api/v2.1/cdt_device",
            "rel": "collection"
        }
    ]
}
[top]

The Execute Endpoint (/api/v2.1/{resource}/execute)

The execute endpoint is used to run an execute command on a specific resource, currently this functionality is limited to:

  • the discover resource (/api/v2.1/discover/execute)
  • the config_build resource (/api/v2.1/config_build/execute)

[top]

GET

A GET request to a {resource}/execute endpoint will run the command associated with that resource.

The additional parameters which can be included in an Execute request are specific to the target Resource and are presented as in the Options table for the endpoint. For details see:

[top]

Example: Running Network Discovery referencing multiple IP Address Ranges and SNMP Credentials

We pass in a discover_config object as a parameter, this object specifies the IP ranges we are targeting with the discovery and the SNMP credentials to use in each IP range. The discover_config being used is:


{
  "iftype": [
    "ethernetCsmacd",
    "fastEther",
    "gigabitEthernet"
  ],
  "ping_count": 2,
  "ping_skip": 256,
  "ping_rate": 512,
  "sysdescr": [
    "include Cisco",
    "include Dell",
    "include HP",
    "include Juniper",
    "include Linux"
  ],
  "ranges": {
    "exclude": [
      "22.200.44.1",
      "22.200.44.254",
      "22.200.44.10",
      "22.200.45.1"
    ],
    "include": [
      "22.200.44.0/24",
      "22.200.45.0/24"
    ]
  },
  "ip_range_configurations": [
    {
      "ip_range": {
        "exclude": [],
        "include": [
          "22.200.46.0/24"
        ]
      },
      "name": "test range",
      "snmp_credentials": [
        2
      ]
    },
    {
      "ip_range": {
        "exclude": [],
        "include": [
          "22.200.46.[250-255]"
        ]
      },
      "name": "test range",
      "snmp_credentials": [
        1
      ]
    }
  ],
  "snmp_credentials": [
    {
      "id": 1,
      "version": 2,
      "community": "public"
    },
    {
      "id": 2,
      "version": 2,
      "community": "notpublic"
    }
  ]
}
cURLPythonRubyResponse

curl \
	-H "Accept: application/json" \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
	-X GET \
	"https://your.statseeker.server/api/v2.1/discover/execute?mode=Discover&discover_config=%7B%22iftype%22:%20%5B%22ethernetCsmacd%22,%20%22fastEther%22,%20%22gigabitEthernet%22%5D,%20%22ping_count%22:%202,%20%22ping_skip%22:%20256,%20%22ping_rate%22:%20512,%20%22sysdescr%22:%20%5B%22include%20Cisco%22,%20%22include%20Dell%22,%20%22include%20HP%22,%20%22include%20Juniper%22,%20%22include%20Linux%22%5D,%20%22ranges%22:%20%7B%22exclude%22:%20%5B%2210.100.44.1%22,%20%2210.100.44.254%22,%20%2210.100.44.10%22,%20%2210.100.45.1%22%5D,%20%22include%22:%20%5B%2210.100.44.0/24%22,%20%2210.100.45.0/24%22%5D%7D,%20%22ip_range_configurations%22:%20%5B%7B%22ip_range%22:%20%7B%22exclude%22:%20%5B%5D,%20%22include%22:%20%5B%2210.100.46.0/24%22%5D%7D,%20%22name%22:%20%22test%20range%22,%20%22snmp_credentials%22:%20%5B2%5D%7D,%20%7B%22ip_range%22:%20%7B%22exclude%22:%20%5B%5D,%20%22include%22:%20%5B%2210.100.46.%5B250-255%5D%22%5D%7D,%20%22name%22:%20%22test%20range%22,%20%22snmp_credentials%22:%20%5B1%5D%7D%5D,%20%22snmp_credentials%22:%20%5B%7B%22id%22:%201,%20%22version%22:%202,%20%22community%22:%20%22public%22%7D,%20%7B%22id%22:%202,%20%22version%22:%202,%20%22community%22:%20%22notpublic%22%7D%5D%7D" 

#!/usr/bin/python

# import requests for handling connection and encoding
import requests
import json

def do_request(server, query, user, pword, reqData = None):
    # Run auth request
    headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
    url = f'https://{server}/ss-auth'
    authData = {'user': user, 'password': pword}
    resp = requests.post(url, headers=headers, data=authData, verify=False)
    headers['Content-Type'] = 'application/json'
    url = f'https://{server}/{query}'
    if resp.status_code == 200:
        # Authentication successful
        myToken = resp.json()
        headers['Authorization'] = f'Bearer {myToken["access_token"]}'
        resp = requests.get(url, headers=headers, verify=False, data=reqData)
    else: 
        #resp.status_code != 200
        # Either Authentication was unsucessful, or API set to use basic auth
        # Try basic auth
        resp = requests.post(url, headers=headers, auth=(user, pword), verify=False, data=reqData)
    return resp

# Statseeker Server IP
server = 'your.statseeker.server'

# credentials
user = 'api_user'
pword = 'user_password'

# API root endpoint
query = 'api/v2.1'

# specify target endpoint
query += '/discover/execute?mode=Discover&discover_config='

# discover config
query += json.dumps({
  "iftype": [
    "ethernetCsmacd",
    "fastEther",
    "gigabitEthernet"
  ],
  "ping_count": 2,
  "ping_skip": 256,
  "ping_rate": 512,
  "sysdescr": [
    "include Cisco",
    "include Dell",
    "include HP",
    "include Juniper",
    "include Linux"
  ],
  "ranges": {
    "exclude": [
      "22.200.44.1",
      "22.200.44.254",
      "22.200.44.10",
      "22.200.45.1"
    ],
    "include": [
      "22.200.44.0/24",
      "22.200.45.0/24"
    ]
  },
  "ip_range_configurations": [
    {
      "ip_range": {
        "exclude": [],
        "include": [
          "22.200.46.0/24"
        ]
      },
      "name": "test range",
      "snmp_credentials": [
        2
      ]
    },
    {
      "ip_range": {
        "exclude": [],
        "include": [
          "22.200.46.[250-255]"
        ]
      },
      "name": "test range",
      "snmp_credentials": [
        1
      ]
    }
  ],
  "snmp_credentials": [
    {
      "id": 1,
      "version": 2,
      "community": "public"
    },
    {
      "id": 2,
      "version": 2,
      "community": "notpublic"
    }
  ]
})

# Run the request
resp = do_request(server, query, user, pword)
if resp.status_code == 200:
    print(resp.status_code)
    print(resp.json())
else:
    print(f'Error: {resp.status_code} {resp.reason}')


require 'rest-client'
require 'json'
require 'base64'

def do_request(server, query, user, password, req_data = nil)
  # Run auth request
  headers = { 'Accept' => 'application/json', 'Content-Type' => 'application/x-www-form-urlencoded' }
  url = "https://#{server}/ss-auth"
  auth_data = { 'user' => user, 'password' => password }
  resp = RestClient.post(url, auth_data, headers: headers)
  headers['Content-Type'] = 'application/json'
  url = "https://#{server}/#{query}"

  if resp.code == 200
    # Authentication successful
    my_token = JSON.parse(resp.body)
    headers['Authorization'] = "Bearer #{my_token['access_token']}"
    resp = RestClient.get(url, headers: headers, payload: req_data)
  else
    # Either Authentication was unsuccessful, or API set to use basic auth
    # Try basic auth
    resp = RestClient.post(url, headers: headers, basic_auth: { user: user, password: password }, payload: req_data)
  end

  resp
end

# Statseeker Server IP
server = 'your.statseeker.server'

# credentials
user = 'api_user'
password = 'user_password'

# API root endpoint
query = 'api/v2.1'

# specify target endpoint
query += '/discover/execute?mode=Discover&discover_config='

# discover config
query += JSON.generate({
  "iftype": [
    "ethernetCsmacd",
    "fastEther",
    "gigabitEthernet"
  ],
  "ping_count": 2,
  "ping_skip": 256,
  "ping_rate": 512,
  "sysdescr": [
    "include Cisco",
    "include Dell",
    "include HP",
    "include Juniper",
    "include Linux"
  ],
  "ranges": {
    "exclude": [
      "22.200.44.1",
      "22.200.44.254",
      "22.200.44.10",
      "22.200.45.1"
    ],
    "include": [
      "22.200.44.0/24",
      "22.200.45.0/24"
    ]
  },
  "ip_range_configurations": [
    {
      "ip_range": {
        "exclude": [],
        "include": [
          "22.200.46.0/24"
        ]
      },
      "name": "test range",
      "snmp_credentials": [
        2
      ]
    },
    {
      "ip_range": {
        "exclude": [],
        "include": [
          "22.200.46.[250-255]"
        ]
      },
      "name": "test range",
      "snmp_credentials": [
        1
      ]
    }
  ],
  "snmp_credentials": [
    {
      "id": 1,
      "version": 2,
      "community": "public"
    },
    {
      "id": 2,
      "version": 2,
      "community": "notpublic"
    }
  ]
})

# Run the request
resp = do_request(server, query, user, password)
if resp.code == 200
  puts resp.code
  puts JSON.parse(resp.body)
else
  puts "Error: #{resp.code} #{resp.body}"
end



{
   "version":"2.1",
   "revision":"16",
   "info":"The Statseeker RESTful API",
   "data":{
      "success":true,
      "errmsg":"ok",
      "time":1724647376,
      "objects":[
         {
            "type":"discover",
            "sequence":29,
            "status":{
               "success":true,
               "errcode":0
            },
            "data_total":0,
            "data":[]
         }
      ]
   }
}

[top]

ID Endpoint (/api/v2.1/{resource}/{id})

The ID endpoint is used to run queries on a specific resource.

[top]

GET

The parameters that may be passed when sending a GET request.

Parameters Type/Valid Values Description
fields A comma separated list of field names
E.g.fields=id,name,location
The list of fields that will be returned in the response. This parameter will be ignored if fields_adv is also specified.
fields_adv A JSON string detailing the fields to be returned
E.g.fields_adv={"Device Name":{"field":"name"}, "IP":{"field":"ipaddress"},"Location":{"field":"sysLocation"},"SNMP Polling":{"field":"snmp_poll","filter":{"query":"=%27off%27"}}}
The list of fields that will be returned in the response
filter An SQL filter string
E.g."SNMP Polling":{"field":"snmp_poll","filter":{"query":"=%27off%27"}}
A filter to be applied to the response data inside of fields_adv
groups A comma separated list of group names or group IDs A list of groups to be used to filter the response data, only data associated with members of the specified groups will be returned
grouping_mode
  • AND
  • OR
The mode to use when processing multiple group parameters
group_by
  • A comma separated array of fields names, or a formula that will be applied to field values
    • Each field name must be enclosed in braces {}
    • The data format must be specified for every timeseries or event field


    Examples:

    • array, 1 value: group_by={name} - aggregate data by entity name, if the request was made to cdt_device, then data would be aggregated by device name
    • array, multiple values: group_by={cdt_device.name},{ifSpeed} - aggregate interface data by device name, and then by interface speed within interfaces on that device
    • array, multiple values and formula: group_by={cdt_device.name},{TxUtil:median} < 50 - aggregate interface data by device name, and then (for each device) by the whether or not the median TxUtil is less than 50

OR

  • Aggregate the results by the Statseeker group/s the specified entity is found in. Each API object lists its entityid_fields in the info block in the description. The API will use the value in these fields as the entityid. If an object lists multiple entityid_fields, then all of them are used (ie. if any of the values are in a group, the row will be considered in that group). One of:
    • ~group~ - returns the group name, requires that ~group~ be listed in the fields parameter
    • ~groupid~ - returns the group id, requires that ~groupid~ be listed in the fields parameter
    • ~group~:<FIELD> - use the specified field as the 'entityid' field rather than the field/s listed in the entityid_fields. Requires that ~group~ be listed in the fields parameter and that the nominated field is specified in the API request (fields parameter, formula fields or linked fields).


    Examples:

    • group_by={~group~} - aggregate data by group, return the group name as a row identifier
    • group_by={~groupid~} - aggregate data by group, return the group ID as a row identifier
    • group_by={~group~:deviceid}- aggregate data by group, use the associated deviceid as an entity identifier, return the group name as a row identifier

For examples of using group_by, see Using 'group_by' for Data Aggregation.

Use when you want to aggregate data across multiple entities, such as total traffic across multiple interfaces.

Requires that:

  • Field names be enclosed in braces {}
  • The fields to be grouped by are specified in the fields parameter of the request
  • The field format be provided for any timeseries/event fields specified in the group_by parameter
    • When using an array, the {field}_aggregation_format parameter is used to specify the format to be applied
    • When using a formula, the format is appended to the field name, separated by a colon (:)

When grouping by groups, an extra group with the name/ID None/null may be returned, containing any rows that weren't in any of the groups.

interval positive integer
E.g.interval=300
The polling interval to be applied to all timeseries metrics specified in the fields parameter. When not specified, the default polling interval of 60 seconds is used.
limit positive integer
E.g.limit=100
The number of items to return per 'page' of the response, see Pagination for details. The API will automatically paginate response data with a default limit=50.
offset positive integer
E.g.offset=100
The number of result items to skip, see Pagination for details. The API will automatically paginate response data with a default offset={limit}.
precision positive integer
E.g. precision=5
The number of decimal places to return for all timeseries metrics specified in the fields parameter.
The default precision value varies between fields, supply this parameter when you want to enforce a specific level of precision across all timeseries fields.
sortmode string

  • novals_after - null values are always sorted after valid values, only valid values are affected by the {field}_sort parameter
  • novals_before - null values are always sorted before valid values, only valid values are affected by the {field}_sort parameter
  • novals_large - null values are counted as larger than any other value and will be sorted to the end of results if the field is sorted ascending, and sorted to the start if sorted descending
  • novals_small - null values are counted as smaller than any other value and will be sorted to the start of results if a field is sorted ascending, and sorted to end if sorted descending
Specify how the response should handle null values.
Default =novals_small, this setting is used in all instances where sortmode is not set.

timefmt string
The syntax for specifying the time format matches that used by STRFTIME.

E.g. timefmt=%A %H:%M:%S (%y-%m-%d)
will return a timestamp in the format
Wednesday 15:44:48 (19-07-17)
The format in which to return timestamps when value_time is set
value_time One of:

  • start - The timestamp at which the event began
  • mid - the midpoint of the start and end timestamps
  • end - the timestamp at which the event finished
  • all - an array of start, mid and end
  • none - do not return a timestamp

E.g.value_time=all

Optionally return a timestamp for returned timeseries data points. Timestamps are return in epoch time unless timefmt is also specified.


When the fields parameter has been specified, the following additional parameters may be used.

Parameters Type/Valid Values Description
{field}_field string A user defined variable name followed by a valid field name for the resource.

E.g.yesterday_RxUtil

See Named Fields for more information and examples.
{field}_formats Comma separated list, see Timeseries Data: Stats, Formats & Options The formats to request from the API for the given field, required for timeseries data fields

Note: a global formats key (formats=) may also be used to apply the same values to all timeseries metrics specified in fields
{field}_formula string Specify an SQL-style formula to be used to populate the field, see Field Formulas for details.

Syntax for referencing other fields within the formula:

  • Configuration field: {field}, e.g. {ping_poll}
  • Timeseries/Event fields must also define a data format: {field:format}, e.g. {ping_rtt:current}
{field}_filter string The filter to apply to the given field. These filters can be either SQL-style filters or extended RegEx filters, for details and examples of applying filters see:

{field}_filter_format string The format to use for the filter, required for timeseries data fields
{field}_interval integer The polling interval (in seconds) to use for the specified field. When used, a field-specific timefilter for the specified field must also be used.

Note: when not specified, the default interval of 60 seconds is used. A global interval key (interval=) may also be used to apply the same values to all timeseries metrics specified in fields
{field}_link string Required when:

  • A resource has multiple links to the same resource type - one of these will be the default link and the others not
  • You want to refence a non-default linked resource

See Multiple Links to the same resource for details.

{field}_object string Required when:

  • A resource has multiple links to the same resource type - one of these will be the default link and the others not
  • You want to refence a non-default linked resource

See Multiple Links to the same resource for details.

{field}_post_filter string The filter to apply to the given field after data aggregation has occurred. This parameter works exactly the same as {field}_filter, except the filter is applied after data aggregation.
{field}_post_formula string The formula to apply to the given field after data aggregation has occurred. This parameter works exactly the same as {field}_formula, except the formula is applied after data aggregation.
{field}_precision positive integer
E.g. {field}_precision=5
The number of decimal places to return for the specified timeseries metric.
The default precision value varies between fields, supply this parameter when you want to enforce a specific level of precision.

Note: a global precision key (precision=) may also be used to apply the same value to all timeseries metrics specified in fields
{field}_timefilter string The timefilter to use for the given field, required for timeseries data fields.

Note: a global timefilter key (timefilter=) may also be used to apply the same values to all timeseries metrics specified in fields
{field}_tz string An alternate timezone to use for the {field}_timefilter.

All timefilters use the Statseeker server's timezone unless an override is specified by supplying {field}_tz.

Note: a global timezone key (tz=) may also be used to apply the same values to all timeseries metrics specified in fields
{field}_sort Comma separated list List specifying the sort hierarchy and direction, in the following format:{field}_sort={rank}{direction} and for Timeseries data:{field}_sort={rank}{direction}{format}
E.g.name_sort=1,asc
RxUtil_sort=1,desc,avg
{field}_stats Comma separated list, see Timeseries Data: Stats, Formats & Options The stats to use for the given field
{field}_aggregation_format One of:

Format Description
95th The 95th percentile of the values
avg The average of the values
cat Concatenation of the values. Not supported for non-scalar formats such as vals
count The number of rows that match, and have a non-null value
count_all The number of rows that match, including NULL values
first The first matching value
last The last matching value
list Concatenate values as per the cat format, but return the output as comma separated list of values
max The maximum value
median The median value
min The minimum value
stddev The standard deviation value
sum The sum of all values
total Similar to sum, but returns 0 instead of NULL if there are only NULL values in the data being aggregated
The aggregation format to use for the specified field

Note: using aggregation, the following rules apply:

  • When the aggregated data is a number - ignore all null values and return the aggregated value required based on non-null values only
  • When the aggregated data is NOT a number - attempt to convert all values to a number prior to aggregation. Any instance of null will result in the aggregated value being returned as null.

[top]

Example: Retrieving Details on a Device

Return specified details on a device with a specified ID. The details I am going to retrieve are:

  • name
  • id
  • community
  • ipaddress
  • snmp_version
cURLPythonRubyResponse

curl \
	-H "Accept: application/json" \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
	-X GET \
	"https://your.statseeker.server/api/v2.1/cdt_device/<DEVICE ID>/?fields=name,id,community,ipaddress,snmp_version&indent=3" 

# import requests for handling connection and encoding
import requests
import json
def do_request(server, query, user, pword):
    # Run auth request
    headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
    url = f'https://{server}/ss-auth'
    authData = {'user': user, 'password': pword}
    resp = requests.post(url, headers=headers, data=authData, verify=False)
    headers['Content-Type'] = 'application/json'
    url = f'https://{server}/{query}'
    print(f'Get Auth Token: {resp.status_code}')
    if resp.status_code == 200:    
        # Authentication successful
        myToken = resp.json()
        headers['Authorization'] = f'Bearer {myToken["access_token"]}'
        resp = requests.get(url, headers=headers, verify=False)
    if resp.status_code == 401:
        print(f'Token auth failed: {resp.status_code}, trying basic auth')
        # Either Authentication was unsuccessful, or API set to use basic auth
        # Try basic auth
        resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
    return resp
# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'api_user'
pword = 'user_password'
# API root endpoint
query = 'api/v2.1'
# specify target endpoint
query += '/cdt_device/<DEVICE ID>'
# specify fields to be returned
query += '/?fields=name,id,community,ipaddress,snmp_version'
# optional response formatting
query += '&indent=3&links=none'
# Run the request
resp = do_request(server, query, user, pword)
if resp.status_code == 200:
    print(resp.status_code)
    print(resp.json())
else:
    print(f'Error: {resp.status_code} {resp.reason}')


# install with: $ gem install rest-client
require "rest_client"
require "json"
require "base64"

def try_basic(server, query, user, pword)
	headers = {
		:content_type => "json"
	}
	url = "https://" + server + "/" + query
	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
	return RestClient::Request.execute(
		:method => :get,
		:url => url,
		:headers => headers,
		:verify_ssl => false
	)
end

def do_request(server, query, user, pword)
    # Run auth request
    headers = {
        :content_type => "application/x-www-form-urlencoded"
    }
    url = "https://" + server + "/ss-auth"
    authData = {
       :user => user,
       :password => pword
    }
    begin
        resp = RestClient::Request.execute(
            :method => :post,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
            :payload => authData
        )
    rescue RestClient::Unauthorized
		# bad credentials
        try_basic(server, query, user, pword)
    else
        # Authentication successful
        headers = {
			:content_type => "application/json"
		}	
        url = "https://" + server + "/" + query
        rdata = JSON.parse(resp)
        headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
        return RestClient::Request.execute(
            :method => :get,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
        )
    end
	rescue RestClient::Unauthorized
		# Statseeker may be configured for basic auth
        try_basic(server, query, user, pword)
end
# Statseeker Server IP
$server = 'your.statseeker.server'
# api user credentials
$user = 'api_user'
$pword = 'user_password'
# api root endpoint
$query = 'api/v2.1'
# specify target endpoint
$query += '/cdt_device/<DEVICE ID>'
# specify fields to be returned
$query += '/?fields=name,id,community,ipaddress,snmp_version'
# optional response formatting
$query += '&indent=3&links=none'
# Run the request
resp = do_request($server, $query, $user, $pword)
puts "#{resp.to_str}"



{
    "version": "2.1",
    "revision": "13",
    "info": "The Statseeker RESTful API",
    "data": {
        "success": true,
        "errmsg": "ok",
        "time": 1623636846,
        "objects": [
            {
                "type": "cdt_device",
                "sequence": 0,
                "status": {
                    "success": true,
                    "errcode": 0
                },
                "data_total": 1,
                "data": [
                    {
                        "name": "Chicago-srv1",
                        "id": <DEVICE ID>,
                        "community": "public",
                        "ipaddress": "10.100.46.11",
                        "snmp_version": 2
                    }
                ]
            }
        ]
    }
}
[top]

PUT

The PUT request can be used to update the fields associated with the specified resource. Not all fields contained within a specific resource may be updated, use the /describe endpoint to view the requirements for a given resource.
[top]

Example: Updating a Group Name
cURLPythonRubyResponse

curl \
	-H "Accept: application/json" \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
	-X PUT \
	"https://your.statseeker.server/api/v2.1/group/<GROUP ID>/?indent=3" \
	-d '{"data":[{"name":"<NEW NAME>"}]}' 

# import requests for handling connection and encoding
import requests
import json
def do_request(server, query, user, pword, reqData):
    # Run auth request
    headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
    url = f'https://{server}/ss-auth'
    authData = {'user': user, 'password': pword}
    resp = requests.post(url, headers=headers, data=authData, verify=False)
    headers['Content-Type'] = 'application/json'
    url = f'https://{server}/{query}'
    print(f'Get Auth Token: {resp.status_code}')
    if resp.status_code == 200:    
        # Authentication successful
        myToken = resp.json()
        headers['Authorization'] = f'Bearer {myToken["access_token"]}'
        resp = requests.put(url, headers=headers, data=reqData, verify=False)
    if resp.status_code == 401:
        print(f'Token auth failed: {resp.status_code}, trying basic auth')
        # Either Authentication was unsuccessful, or API set to use basic auth
        # Try basic auth
        resp = requests.put(url, headers=headers, auth=(user, pword), data=reqData, verify=False)
    return resp

# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'api_user'
pword = 'user_password'
# API root endpoint
query = 'api/v2.1'
# specify target endpoint
query += '/group/<GROUP ID>'
# optional response formatting
query += '/?indent=3&links=none'
# data
reqData = json.dumps({"data":[{"name":"<NEW NAME>"}]})
# Run the request
resp = do_request(server, query, user, pword, reqData)
if resp.status_code == 200:
    print(resp.status_code)
    print(resp.json())
else:
    print(f'Error: {resp.status_code} {resp.reason}')



# install with: $ gem install rest-client
require "rest_client"
require "json"
require "base64"

def try_basic(server, query, user, pword, reqData)
	headers = {
		:content_type => "application/json"
	}
	url = "https://" + server + "/" + query
	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
	return RestClient::Request.execute(
		:method => :put,
		:url => url,
		:headers => headers,
		:verify_ssl => false,
		:payload => reqData
	)
end

def do_request(server, query, user, pword, reqData)
    # Run auth request
    headers = {
        :content_type => "application/x-www-form-urlencoded"
    }
    url = "https://" + server + "/ss-auth"
    authData = {
       :user => user,
       :password => pword
    }
    begin
        resp = RestClient::Request.execute(
            :method => :post,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
            :payload => authData
        )
    rescue RestClient::Unauthorized
		# bad credentials
        try_basic(server, query, user, pword, reqData)
    else		
        # Authentication successful
		headers = {
		:content_type => "application/json"
		}	
        url = "https://" + server + "/" + query
        rdata = JSON.parse(resp)
        headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
        return RestClient::Request.execute(
			:method => :put,
			:url => url,
			:headers => headers,
			:verify_ssl => false,
			:payload => reqData
        )
    end
	rescue RestClient::Unauthorized
		# Statseeker may be configured for basic auth
        try_basic(server, query, user, pword, reqData)
end
# Statseeker Server IP
$server = 'your.statseeker.server'
# api user credentials
$user = 'api_user'
$pword = 'user_password'
# api root endpoint
$query = 'api/v2.1'
# specify target endpoint
$query += '/group/<GROUP ID>'
# optional response formatting
$query += '/?indent=3&links=none'
# configure payload
$reqData = '{"data":[{"name":"<NEW NAME>"}]}'
# Run the request
resp = do_request($server, $query, $user, $pword, $reqData)
puts "#{resp.to_str}"



{
   "version":"2.1",
   "revision":"11",
   "info":"The Statseeker RESTful API",
   "data":{
      "success":true,
      "errmsg":"ok",
      "time":1623637436
   }
}
[top]

DELETE

The DELETE request can be used to delete the specified resource.

[top]

Example: Deleting a Group
cURLPythonRubyResponse

curl \
	-H "Accept: application/json" \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
	-X DELETE \
	"https://your.statseeker.server/api/v2.1/group/<GROUP ID>/?indent=3"

# import requests for handling connection and encoding
import requests
import json
def do_request(server, query, user, pword, reqData):
    # Run auth request
    headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
    url = f'https://{server}/ss-auth'
    authData = {'user': user, 'password': pword}
    resp = requests.post(url, headers=headers, data=authData, verify=False)
    headers['Content-Type'] = 'application/json'
    url = f'https://{server}/{query}'
    print(f'Get Auth Token: {resp.status_code}')
    if resp.status_code == 200:    
        # Authentication successful
        myToken = resp.json()
        headers['Authorization'] = f'Bearer {myToken["access_token"]}'
        resp = requests.delete(url, headers=headers, data=reqData, verify=False)
    if resp.status_code == 401:
        print(f'Token auth failed: {resp.status_code}, trying basic auth')
        # Either Authentication was unsuccessful, or API set to use basic auth
        # Try basic auth
        resp = requests.delete(url, headers=headers, auth=(user, pword), data=reqData, verify=False)
    return resp

# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'api_user'
pword = 'user_password'
# API root endpoint
query = 'api/v2.1'
# specify target endpoint
query += '/group/<GROUP ID>'
# optional response formatting
query += '/?indent=3&links=none'
# data
# Run the request
resp = do_request(server, query, user, pword)
if resp.status_code == 200:
    print(resp.status_code)
    print(resp.json())
else:
    print(f'Error: {resp.status_code} {resp.reason}') 


# install with: $ gem install rest-client
require "rest_client"
require "json"
require "base64"

def try_basic(server, query, user, pword, reqData)
	headers = {
		:content_type => "application/json"
	}
	url = "https://" + server + "/" + query
	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
	return RestClient::Request.execute(
		:method => :delete,
		:url => url,
		:headers => headers,
		:verify_ssl => false,
		:payload => reqData
	)
end

def do_request(server, query, user, pword, reqData)
    # Run auth request
    headers = {
        :content_type => "application/x-www-form-urlencoded"
    }
    url = "https://" + server + "/ss-auth"
    authData = {
       :user => user,
       :password => pword
    }
    begin
        resp = RestClient::Request.execute(
            :method => :post,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
            :payload => authData
        )
    rescue RestClient::Unauthorized
		# bad credentials
        try_basic(server, query, user, pword, reqData)
    else		
        # Authentication successful
		headers = {
		:content_type => "application/json"
		}	
        url = "https://" + server + "/" + query
        rdata = JSON.parse(resp)
        headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
        return RestClient::Request.execute(
			:method => :delete,
			:url => url,
			:headers => headers,
			:verify_ssl => false,
			:payload => reqData
        )
    end
	rescue RestClient::Unauthorized
		# Statseeker may be configured for basic auth
        try_basic(server, query, user, pword, reqData)
end
# Statseeker Server IP
$server = 'your.statseeker.server'
# api user credentials
$user = 'api_user'
$pword = 'user_password'
# api root endpoint
$query = 'api/v2.1'
# specify target endpoint
$query += '/group/<GROUP ID>'
# optional response formatting
$query += '/?indent=3&links=none'
# Run the request
resp = do_request($server, $query, $user, $pword)
puts "#{resp.to_str}"


{
   "version":"2.1",
   "revision":"11",
   "info":"The Statseeker RESTful API",
   "data":{
      "success":true,
      "errmsg":"ok",
      "time":1623637436
   }
}
[top]

Field Endpoint (/api/v2.1/{resource}/{id}/{field})

The Field endpoint is used to run queries on a specific field within a specified resource, use the /describe endpoint to view the field restrictions for a given resource.

[top]

GET

The parameters that may be passed when sending a GET request behave exactly like the {field}_* parameters for the Resource and ID endpoints. When targeting timeseries metrics, the following parameters may be specified.

Parameters Type/Valid Values Description
formats Comma separated list, see Timeseries Data: Stats, Formats & Options The formats to request from the API for the given field, required for timeseries data fields
formula string Specify an SQL-style formula to be used to populate the field, see Field Formulas for details.
filter string The filter to apply to the given field. These filters can be either SQL-style filters or extended RegEx filters, for details and examples of applying filters see:

filter_format string The format to use for the filter, required for timeseries data fields
interval integer The polling interval (in seconds) to use for the specified field. When used, a field-specific timefilter for the specified field must also be used.

Note: when not specified, the default interval of 60 seconds is used.
post_filter string The filter to apply to the given field after data aggregation has occurred. This parameter works exactly the same as filter, except the filter is applied after data aggregation.
post_formula string The formula to apply to the given field after data aggregation has occurred. This parameter works exactly the same as formula, except the formula is applied after data aggregation.
precision positive integer
E.g. {field}_precision=5
The number of decimal places to return for the specified timeseries metric.
The default precision value varies between fields, supply this parameter when you want to enforce a specific level of precision.
timefilter string The timefilter to use for the given field, required for timeseries data fields.
tz string An alternate timezone to use for the timefilter.

All timefilters use the Statseeker server's timezone unless an override is specified by supplying tz.
stats Comma separated list, see Timeseries Data: Stats, Formats & Options The stats to use for the given field
aggregation_format One of:

Format Description
95th The 95th percentile of the values
avg The average of the values
cat Concatenation of the values. Not supported for non-scalar formats such as vals
count The number of rows that match, and have a non-null value
count_all The number of rows that match, including NULL values
first The first matching value
last The last matching value
list Concatenate values as per the cat format, but return the output as comma separated list of values
max The maximum value
median The median value
min The minimum value
stddev The standard deviation value
sum The sum of all values
total Similar to sum, but returns 0 instead of NULL if there are only NULL values in the data being aggregated
The aggregation format to use for the specified field

Note: using aggregation, the following rules apply:

  • When the aggregated data is a number - ignore all null values and return the aggregated value required based on non-null values only
  • When the aggregated data is NOT a number - attempt to convert all values to a number prior to aggregation. Any instance of null will result in the aggregated value being returned as null.

[top]

Example: Returning a User's Time Zone
cURLPythonRubyResponse

curl \
	-H "Accept: application/json" \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
	-X GET \
	"https://your.statseeker.server/api/v2.1/user/<USER ID>/tz/?indent=3"

# import requests for handling connection and encoding
import requests
import json
def do_request(server, query, user, pword):
    # Run auth request
    headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
    url = f'https://{server}/ss-auth'
    authData = {'user': user, 'password': pword}
    resp = requests.post(url, headers=headers, data=authData, verify=False)
    headers['Content-Type'] = 'application/json'
    url = f'https://{server}/{query}'
    print(f'Get Auth Token: {resp.status_code}')
    if resp.status_code == 200:    
        # Authentication successful
        myToken = resp.json()
        headers['Authorization'] = f'Bearer {myToken["access_token"]}'
        resp = requests.get(url, headers=headers, verify=False)
    if resp.status_code == 401:
        print(f'Token auth failed: {resp.status_code}, trying basic auth')
        # Either Authentication was unsuccessful, or API set to use basic auth
        # Try basic auth
        resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
    return resp

# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'api_user'
pword = 'user_password'
# API root endpoint
query = 'api/v2.1'
# specify target endpoint
query += '/user/<USER ID>/tz'
# optional response formatting
query += '/?indent=3&links=none'
# Run the request
resp = do_request(server, query, user, pword)
if resp.status_code == 200:
    print(resp.status_code)
    print(resp.json())
else:
    print(f'Error: {resp.status_code} {resp.reason}') 


# install with: $ gem install rest-client
require "rest_client"
require "json"
require "base64"

def try_basic(server, query, user, pword)
	headers = {
		:content_type => "json"
	}
	url = "https://" + server + "/" + query
	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
	return RestClient::Request.execute(
		:method => :get,
		:url => url,
		:headers => headers,
		:verify_ssl => false
	)
end

def do_request(server, query, user, pword)
    # Run auth request
    headers = {
        :content_type => "application/x-www-form-urlencoded"
    }
    url = "https://" + server + "/ss-auth"
    authData = {
       :user => user,
       :password => pword
    }
    begin
        resp = RestClient::Request.execute(
            :method => :post,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
            :payload => authData
        )
    rescue RestClient::Unauthorized
		# bad credentials
        try_basic(server, query, user, pword)
    else
        # Authentication successful
        headers = {
			:content_type => "application/json"
		}	
        url = "https://" + server + "/" + query
        rdata = JSON.parse(resp)
        headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
        return RestClient::Request.execute(
            :method => :get,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
        )
    end
	rescue RestClient::Unauthorized
		# Statseeker may be configured for basic auth
        try_basic(server, query, user, pword)
end
# Statseeker Server IP
$server = 'your.statseeker.server'
# api user credentials
$user = 'api_user'
$pword = 'user_password'
# api root endpoint
$query = 'api/v2.1'
# specify target endpoint
$query += '/user/<USER ID>/tz'
# optional response formatting
$query += '/?indent=3&links=none'
# Run the request
resp = do_request($server, $query, $user, $pword)
puts "#{resp.to_str}"


{
   "version":"2.1",
   "revision":"11",
   "info":"The Statseeker RESTful API",
   "data":{
      "success":true,
      "errmsg":"ok",
      "time":1623638836,
      "objects":[
         {
            "type":"user",
            "sequence":0,
            "status":{
               "success":true,
               "errcode":0
            },
            "data_total":1,
            "data":[
               {
                  "tz":"Australia/Brisbane",
                  "id":<USER ID>
               }
            ]
         }
      ]
   }
}
[top]

PUT

The PUT request can be used to update the specified field. Not all fields contained within a specific resource may be updated, use the /describe endpoint to view the restrictions for a given resource. The data object must contain a value key containing the new value/s to be set for the field.
[top]

Example: Updating a User's Time Zone
cURLPythonRubyResponse

curl \
	-H "Accept: application/json" \
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
	-X PUT \
	"https://your.statseeker.server/api/v2.1/user/<USER ID>/tz/?indent=3" \
	-d '{"value":"Europe/Paris"}'

# import requests for handling connection and encoding
import requests
import json
def do_request(server, query, user, pword, reqData):
    # Run auth request
    headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
    url = f'https://{server}/ss-auth'
    authData = {'user': user, 'password': pword}
    resp = requests.post(url, headers=headers, data=authData, verify=False)
    headers['Content-Type'] = 'application/json'
    url = f'https://{server}/{query}'
    print(f'Get Auth Token: {resp.status_code}')
    if resp.status_code == 200:    
        # Authentication successful
        myToken = resp.json()
        headers['Authorization'] = f'Bearer {myToken["access_token"]}'
        resp = requests.put(url, headers=headers, data=reqData, verify=False)
    if resp.status_code == 401:
        print(f'Token auth failed: {resp.status_code}, trying basic auth')
        # Either Authentication was unsuccessful, or API set to use basic auth
        # Try basic auth
        resp = requests.put(url, headers=headers, auth=(user, pword), data=reqData, verify=False)
    return resp

# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'api_user'
pword = 'user_password'
# API root endpoint
query = 'api/v2.1'
# specify target endpoint
query += '/user/<USER ID>/tz'
# optional response formatting
query += '/?indent=3&links=none'
# data
reqData = json.dumps({"value":"Europe/Paris"})
# Run the request
resp = do_request(server, query, user, pword, reqData)
if resp.status_code == 200:
    print(resp.status_code)
    print(resp.json())
else:
    print(f'Error: {resp.status_code} {resp.reason}')


# install with: $ gem install rest-client
require "rest_client"
require "json"
require "base64"

def try_basic(server, query, user, pword, reqData)
	headers = {
		:content_type => "application/json"
	}
	url = "https://" + server + "/" + query
	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
	return RestClient::Request.execute(
		:method => :put,
		:url => url,
		:headers => headers,
		:verify_ssl => false,
		:payload => reqData
	)
end

def do_request(server, query, user, pword, reqData)
    # Run auth request
    headers = {
        :content_type => "application/x-www-form-urlencoded"
    }
    url = "https://" + server + "/ss-auth"
    authData = {
       :user => user,
       :password => pword
    }
    begin
        resp = RestClient::Request.execute(
            :method => :post,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
            :payload => authData
        )
    rescue RestClient::Unauthorized
		# bad credentials
        try_basic(server, query, user, pword, reqData)
    else		
        # Authentication successful
		headers = {
		:content_type => "application/json"
		}	
        url = "https://" + server + "/" + query
        rdata = JSON.parse(resp)
        headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
        return RestClient::Request.execute(
			:method => :put,
			:url => url,
			:headers => headers,
			:verify_ssl => false,
			:payload => reqData
        )
    end
	rescue RestClient::Unauthorized
		# Statseeker may be configured for basic auth
        try_basic(server, query, user, pword, reqData)
end
# Statseeker Server IP
$server = 'your.statseeker.server'
# api user credentials
$user = 'api_user'
$pword = 'user_password'
# api root endpoint
$query = 'api/v2.1'
# specify target endpoint
$query += '/user/<USER ID>/tz'
# optional response formatting
$query += '/?indent=3&links=none'
# configure payload
$reqData = '{"value":"Europe/Paris"}'
# Run the request
resp = do_request($server, $query, $user, $pword, $reqData)
puts "#{resp.to_str}"



{
  "info": "The Statseeker RESTful API",
  "data": {
    "errmsg": "ok",
    "success": true,
    "time": 1496193864
  },
  "api_version": "2.1"
}
[top]



Common Resources: Examples and Sample Code

Most of the processes and objects that you are used to interacting with in Statseeker (network discovery, users, groups, devices, interfaces, alerts, etc.) are exposed as resources from the API standpoint and through querying the API these resources can be returned as data objects which you can review and modify.

Statseeker exposes many resources via the API but most API users will spend the majority of their time working with just a few. The most commonly used resources are presented below along with examples of interacting with those resources.

Note:

[top]

Users

The User resource allows you to interact with (create, edit, delete, and report on) Statseeker user records.

The user object
Field ID Field Title Type Get, Add, Update Description
api API Access string G, U, A User API access permission, one of:

  • r
  • rw
auth Authentication method string G, U, A User authentication method, one of:

  • File
  • LDAP
  • RADIUS
  • SAML
auth_refresh Authentication Refresh integer G, U, A The time allowed after a token has expired that it will be refreshed (in seconds)
auth_ttl Authentication TTL integer G, U, A The TTL for authentication tokens (in seconds)
email Email string G, U, A User email address
exportDateFormat Date Format string G, U, A User specified Date Format
id ID integer G User Identifier
is_admin Is Admin integer G, U, A Whether the user has admin access, one of:

  • 0
  • 1
name Name string G, A (required) User name
password Password string G, U, A User password
reportRowSpacing Report Row Spacing string G, U, A The report row spacing preference for the user
top_n Top N integer G, U, A The default Top N number for the user
tz Time Zone string G, U, A User time zone

[top]

Example: Creating a New User

cURLPythonRubyResponse

curl \ 
	-H "Accept: application/json" \ 
	-H "Content-Type: application/json" \
	-X POST \
	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
	"https://your.statseeker.server/api/v2.1/user/?indent=3" \
	-d '{"data":[{"name":"<USER NAME>","password":"<PASSWORD>","auth":"<AUTHENTICATION METHOD>","email":"<EMAIL ADDRESS>","api":"<API PERMISSION>","tz":"<TIMEZONE>"}]}' 

# import requests for handling connection and encoding
import requests
import json
def do_request(server, query, user, pword, reqData):
    # Run auth request
    headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
    url = f'https://{server}/ss-auth'
    authData = {'user': user, 'password': pword}
    resp = requests.post(url, headers=headers, data=authData, verify=False)
    headers['Content-Type'] = 'application/json'
    url = f'https://{server}/{query}'
    print(f'Get Auth Token: {resp.status_code}')
    if resp.status_code == 200:    
        # Authentication successful
        myToken = resp.json()
        headers['Authorization'] = f'Bearer {myToken["access_token"]}'
        resp = requests.post(url, headers=headers, data=reqData, verify=False)
    if resp.status_code == 401:
        print(f'Token auth failed: {resp.status_code}, trying basic auth')
        # Either Authentication was unsuccessful, or API set to use basic auth
        # Try basic auth
        resp = requests.post(url, headers=headers, auth=(user, pword), data=reqData, verify=False)
    return resp

# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'api_user'
pword = 'user_password'
# API root endpoint
query = 'api/v2.1'
# specify target endpoint
query += '/user'
# optional response formatting
query += '/?indent=3&links=none'
# data
reqData = json.dumps({"data":[{"name":"<USER NAME>","password":"<PASSWORD>","auth":"<AUTHENTICATION METHOD>","email":"<EMAIL ADDRESS>","api":"<API PERMISSION>","tz":"<TIMEZONE>"}]})
# Run the request
resp = do_request(server, query, user, pword, reqData)
if resp.status_code == 200:
    print(resp.status_code)
    print(resp.json())
else:
    print(f'Error: {resp.status_code} {resp.reason}') 

# install with: $ gem install rest-client
require "rest_client"
require "json"
require "base64"

def try_basic(server, query, user, pword, reqData)
	headers = {
		:content_type => "application/json"
	}
	url = "https://" + server + "/" + query
	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
	return RestClient::Request.execute(
		:method => :post,
		:url => url,
		:headers => headers,
		:verify_ssl => false,
		:payload => reqData
	)
end

def do_request(server, query, user, pword, reqData)
    # Run auth request
    headers = {
        :content_type => "application/x-www-form-urlencoded"
    }
    url = "https://" + server + "/ss-auth"
    authData = {
       :user => user,
       :password => pword
    }
    begin
        resp = RestClient::Request.execute(
            :method => :post,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
            :payload => authData
        )
    rescue RestClient::Unauthorized
		# bad credentials
        try_basic(server, query, user, pword, reqData)
    else		
        # Authentication successful
		headers = {
		:content_type => "application/json"
		}	
        url = "https://" + server + "/" + query
        rdata = JSON.parse(resp)
        headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
        return RestClient::Request.execute(
			:method => :post,
			:url => url,
			:headers => headers,
			:verify_ssl => false,
			:payload => reqData
        )
    end
	rescue RestClient::Unauthorized
		# Statseeker may be configured for basic auth
        try_basic(server, query, user, pword, reqData)
end
# Statseeker Server IP
$server = 'your.statseeker.server'
# api user credentials
$user = 'api_user'
$pword = 'user_password'
# api root endpoint
$query = 'api/v2.1'
# specify target endpoint
$query += '/user'
# optional response formatting
$query += '/?indent=3&links=none'
# configure payload
# define payload in json format
$reqData = '{"data":[{"name":"<USER NAME>","password":"<PASSWORD>","auth":"<AUTHENTICATION METHOD>","email":"<EMAIL ADDRESS>","api":"<API PERMISSION>","tz":"<TIMEZONE>"}]}'
# Run the request
resp = do_request($server, $query, $user, $pword, $reqData)
puts "#{resp.to_str}"


{
   "version":"2.1",
   "revision":"11",
   "info":"The Statseeker RESTful API",
   "data":{
      "success":true,
      "errmsg":"ok",
      "time":1623643182,
      "objects":[
         {
            "type":"user",
            "sequence":1,
            "status":{
               "success":true,
               "errcode":0
            },
            "data_total":1,
            "data":[
                  "api":"<API PERMISSION>",
                  "auth":"<AUTHENTICATION METHOD>",
                  "email":"<EMAIL ADDRESS>",
                  "name":"<USER NAME>",
                  "password":"<PASSWORD>",
                  "tz":"<TIMEZONE>",
                  "id":94551,
                  "is_admin":0
               }
            ]
         }
      ]
   }
}
[top]

Example: Updating an Existing User

cURLPythonRubyResponse

curl \ 
	-H "Accept: application/json" \ 
	-H "Content-Type: application/json" \
	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
	-X PUT \
	"https://your.statseeker.server/api/v2.1/user/<USER ID>?indent=3" \
	-d '{"data":[{"api":"<API PERMISSION>","tz":"<NEW TIMEZONE>"}]}' 

# import requests for handling connection and encoding
import requests
import json
def do_request(server, query, user, pword, reqData):
    # Run auth request
    headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
    url = f'https://{server}/ss-auth'
    authData = {'user': user, 'password': pword}
    resp = requests.post(url, headers=headers, data=authData, verify=False)
    headers['Content-Type'] = 'application/json'
    url = f'https://{server}/{query}'
    print(f'Get Auth Token: {resp.status_code}')
    if resp.status_code == 200:    
        # Authentication successful
        myToken = resp.json()
        headers['Authorization'] = f'Bearer {myToken["access_token"]}'
        resp = requests.put(url, headers=headers, data=reqData, verify=False)
    if resp.status_code == 401:
        print(f'Token auth failed: {resp.status_code}, trying basic auth')
        # Either Authentication was unsuccessful, or API set to use basic auth
        # Try basic auth
        resp = requests.put(url, headers=headers, auth=(user, pword), data=reqData, verify=False)
    return resp

# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'api_user'
pword = 'user_password'
# API root endpoint
query = 'api/v2.1'
# specify target endpoint
query += '/user/<USER ID>'
# optional response formatting
query += '/?indent=3&links=none'
# data
reqData = json.dumps({"data":[{"api":"<API PERMISSION>","tz":"<NEW TIMEZONE>"}]})
# Run the request
resp = do_request(server, query, user, pword, reqData)
if resp.status_code == 200:
    print(resp.status_code)
    print(resp.json())
else:
    print(f'Error: {resp.status_code} {resp.reason}')


# install with: $ gem install rest-client
require "rest_client"
require "json"
require "base64"

def try_basic(server, query, user, pword, reqData)
	headers = {
		:content_type => "application/json"
	}
	url = "https://" + server + "/" + query
	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
	return RestClient::Request.execute(
		:method => :put,
		:url => url,
		:headers => headers,
		:verify_ssl => false,
		:payload => reqData
	)
end

def do_request(server, query, user, pword, reqData)
    # Run auth request
    headers = {
        :content_type => "application/x-www-form-urlencoded"
    }
    url = "https://" + server + "/ss-auth"
    authData = {
       :user => user,
       :password => pword
    }
    begin
        resp = RestClient::Request.execute(
            :method => :post,
            :url => url,
            :headers => headers,
            :verify_ssl => false,
            :payload => authData
        )
    rescue RestClient::Unauthorized
		# bad credentials
        try_basic(server, query, user, pword, reqData)
    else		
        # Authentication successful
		headers = {
		:content_type => "application/json"
		}	
        url = "https://" + server + "/" + query
        rdata = JSON.parse(resp)
        headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
        return RestClient::Request.execute(
			:method => :put,
			:url => url,
			:headers => headers,
			:verify_ssl => false,
			:payload => reqData
        )
    end
	rescue RestClient::Unauthorized
		# Statseeker may be configured for basic auth
        try_basic(server, query, user, pword, reqData)
end
# Statseeker Server IP
$server = 'your.statseeker.server'
# api user credentials
$user = 'api_user'
$pword = 'user_password'
# api root endpoint
$query = 'api/v2.1'
# specify target endpoint
$query += '/user/<USER ID>'
# optional response formatting
$query += '/?indent=3&links=none'
# configure payload
$reqData = '{"data":[{"api":"<API PERMISSION>","tz":"<NEW TIMEZONE>"}]}'
# Run the request
resp = do_request($server, $query, $user, $pword, $reqData)
puts "#{resp.to_str}"


{
   "version":"2.1",
   "revision":"11",
   "info":"The Statseeker RESTful API",
   "data":{
      "success":true,
      "errmsg":"ok",
      "time":1623644832
   }
}
[top]

Devices (cdt_device)

The cdt_device resource allows you to interact with your currently discovered network devices.

The cdt_device object
Field ID Field Title Type Get, Add, Update Description
id ID integer G The entity identifier
name Name string G The entity name
deviceid Device ID integer G The ID of the parent device
idx Index string G The base SNMP index for this entity
table Table string G The table to which the entity belongs
poll Poll State string G, U The poll state of the entity

  • on
  • off
auth_method SNMPv3 Authentication Method string G, A, U Authentication method for SNMPv3 devices
auth_pass SNMPv3 Authentication Password string G, A, U Authentication password for SNMPv3 devices
auth_user SNMPv3 Authentication Username string G, A, U Authentication user for SNMPv3 devices
chassisId Chassis ID string G The string value used to identify the chassis component associated with the local system.
community Community string G, A, U The community string status of the device
context SNMPv3 Context string G, A, U Context for SNMPv3 devices
custom_data_details Custom Data Details string G, U A JSON string object indicating which custom entities have been found during a discovery
default_poller Default Poller string G, U The poller where ping metrics for this device are polled from
discover_getNext Use GetNext string G, U Walk this device using SNMP getNext instead of getBulk
discover_minimal Use Minimal Walk string G, U Walk this device using a minimal set of oids
discover_snmpv1 Use SNMPv1 string G, U Walk this device using SNMPv1
hostname Hostname string G, A, U The hostname of the device
ipaddress IP Address string G, A, U The IP address of the device
latitude Latitude float G, A, U The user defined latitude of the device's location
longitude Longitude float G, A, U The user defined longitude of the device's location
manual_name User Defined Name string G, U The user defined name of the device
memorySize Memory Size integer G The amount of physical read-write memory contained by the entity
mis MAC/IP/Switch Collection State string G, U Include this device in the MIS report calculations
ping_dup Ping Duplicate integer G Number of duplicate ping responses received from the default poller
Timeseries Data: Stats, Formats & Options
ping_jitter Ping Jitter float G The ping rtt jitter to this device in ms to 3 decimal places from the default poller
Timeseries Data: Stats, Formats & Options
ping_lost Ping Lost integer G Number of times that a ping request was lost from the default poller
Timeseries Data: Stats, Formats & Options
ping_lost_percent Ping Lost Percent integer G The percentage of lost ping packets from the default poller
Timeseries Data: Stats, Formats & Options
ping_outage Ping Outage integer G, U Number of seconds to wait before a device is considered to be down
ping_poll Ping Poll string G, A, U The ping polling status of the device from the default poller
ping_received Ping Received integer G Number of ping request received from the default poller
Timeseries Data: Stats, Formats & Options
ping_rtt Ping RTT float G The current 1 minute average ping rtt to this device in ms to 3 decimal places from the default poller
Timeseries Data: Stats, Formats & Options
ping_rtt_max Maximum Ping RTT float G The maximum ping rtt to this device in ms to 3 decimal places from the default poller
Timeseries Data: Stats, Formats & Options
ping_rtt_min Minimum Ping RTT float G The minimum ping rtt to this device in ms to 3 decimal places from the default poller
Timeseries Data: Stats, Formats & Options
ping_sent Ping Sent integer G Number of ping request sent from the default poller
Timeseries Data: Stats, Formats & Options
ping_state Ping State string G, U The current ping state of the device from the default poller, one of:

  • unknown - Device ping status is not in any of the other states
  • up - Device ping status is up
  • down - Device ping status is down
  • poller_down - The poller responsible for polling the Device is down
  • disabled - Device has polling disabled for this Poller

Can be combined with an event format for event-based analytics, see Event Formats

priv_method SNMPv3 Privacy Method string G, A, U Privacy method for SNMPv3 devices
priv_pass SNMPv3 Privacy Password string G, A, U Privacy password for SNMPv3 devices
region Region string G, U The region of the device
retired Retired string G The device has been Retired
site Site string G, U The site location of the device
snmpEngineID SNMP Engine ID string G, U An SNMP engine's administratively-unique identifier
snmp_maxoid SNMP Max OID integer G, U Maximum number of oids to poll in a single request
snmp_poll SNMP Poll string G, A, U The SNMP polling status of the device
snmp_state SNMP State string G, U The current SNMP state of the device from the default poller, one of:

  • unknown - Device SNMP status is not in any of the other states
  • up - Device SNMP status is up
  • down - Device SNMP status is down
  • poller_down - The poller responsible for polling the Device is down
  • disabled - Device has polling disabled for this Poller

Can be combined with an event format for event-based analytics, see Event Formats

snmp_version SNMP Version integer G, A, U The SNMP version of the device
sysContact Contact string G, U The textual identification of the contact person for the entity
sysDescr System Description string G, U A textual description of the entity
sysLocation Location string G, U The physical location of the entity
sysName System Name string G, U An administratively-assigned name for the entity
sysObjectID Object ID string G, U The vendor's authoritative identification of the network management subsystem contained in the entity
sysServices Services integer G, U A value which indicates the set of services that the entity may potentially offer
vendor Vendor string G The vendor name for the device
Links

This resource has links to the following:

  • macLink - Link to MAC (mac)
  • merakiDeviceLink - Link to Meraki Device (cdt_meraki_device)
  • [top]

    Example: Configuring a Device as Ping-Only

    cURLPythonRubyResponse
    
    curl \ 
    	-H "Accept: application/json" \ 
    	-H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    	-X PUT \
    	"https://your.statseeker.server/api/v2.1/cdt_device/<DEVICE ID>/?indent=3" \
    	-d '{"data":[{"ping_poll":"on","snmp_poll":"off"}]}'
    
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword, reqData):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.put(url, headers=headers, data=reqData, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.put(url, headers=headers, auth=(user, pword), data=reqData, verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/cdt_device/<DEVICE ID>'
    # optional response formatting
    query += '/?indent=3&links=none'
    # data
    reqData = json.dumps({"data":[{"ping_poll":"on","snmp_poll":"off"}]})
    # Run the request
    resp = do_request(server, query, user, pword, reqData)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword, reqData)
    	headers = {
    		:content_type => "application/json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :put,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false,
    		:payload => reqData
    	)
    end
    
    def do_request(server, query, user, pword, reqData)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword, reqData)
        else		
            # Authentication successful
    		headers = {
    		:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
    			:method => :put,
    			:url => url,
    			:headers => headers,
    			:verify_ssl => false,
    			:payload => reqData
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword, reqData)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/cdt_device/<DEVICE ID>'
    # optional response formatting
    $query += '/?indent=3&links=none'
    # configure payload
    $reqData = '{"data":[{"ping_poll":"on","snmp_poll":"off"}]}'
    # Run the request
    resp = do_request($server, $query, $user, $pword, $reqData)
    puts "#{resp.to_str}"
    
    
    
    {
        "version": "2.1",
        "revision": "13",
        "info": "The Statseeker RESTful API",
        "data": {
            "success": true,
            "errmsg": "ok",
            "time": 1623646976,
            "objects": [
                {
                    "type": "cdt_device",
                    "sequence": 1,
                    "status": {
                        "success": true,
                        "errcode": 0
                    },
                    "data_total": 1,
                    "data": [
                        {
                            "name": "Houston-swt1",
                            "id": <DEVICE ID>,
                            "community": "public",
                            "ipaddress": "10.100.47.253",
                            "snmp_version": 2,
                            "poll": "off",
                            "ping_poll": "on"
                        }
                    ]
                }
            ]
        }
    }
    
    
    [top]

    Example: Returning Details on all Ping-Only Devices

    cURLPythonRubyResponse
    
    curl \
    	-H "Accept: application/json" \
    	-H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    	-X GET \
    	"https://your.statseeker.server/api/v2.1/cdt_device/?fields=name,ipaddress,sysLocation,snmp_poll,ping_poll&snmp_poll_filter=IS(%27off%27)&ping_poll_filter=IS(%27on%27)" 
    
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.get(url, headers=headers, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/cdt_device'
    # specify fields to be returned
    query += '/?fields=name,ipaddress,sysLocation,snmp_poll,ping_poll'
    # Filters
    query += '&snmp_poll_filter=IS("off")&ping_poll_filter=IS("on")'
    # optional response formatting
    query += '&indent=3&links=none'
    # Run the request
    resp = do_request(server, query, user, pword)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword)
    	headers = {
    		:content_type => "json"
    	}
    	url = "https://" + server + '/' + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :get,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false
    	)
    end
    
    def do_request(server, query, user, pword)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword)
        else
            # Authentication successful
            headers = {
    			:content_type => "application/json"
    		}	
            url = "https://" + server + '/' + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
                :method => :get,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/cdt_device'
    # specify fields to be returned
    $query += '/?fields=name,ipaddress,sysLocation,snmp_poll,ping_poll'
    # Filters
    $query += '&snmp_poll_filter=IS("off")&ping_poll_filter=IS("on")'
    # optional response formatting
    $query += '&indent=3&links=none'
    # Run the request
    resp = do_request($server, $query, $user, $pword)
    puts "#{resp.to_str}"
    
    
    {
       "version":"2.1",
       "revision":"11",
       "info":"The Statseeker RESTful API",
       "data":{
          "success":true,
          "errmsg":"ok",
          "time":1623647384,
          "objects":[
             {
                "type":"cdt_device",
                "sequence":1,
                "status":{
                   "success":true,
                   "errcode":0
                },
                "data_total":2,
                "data":[
                   {
                      "name":"Houston-swt1",
                      "ipaddress":"10.100.47.253",
                      "sysLocation":"Houston",
                      "snmp_poll":"off",
                      "ping_poll":"on",
                      "id":425
                   },
    			   {				  
    				  "name":"Adelaide-swt1",
    				  "ipaddress":"10.100.89.253",
    				  "sysLocation":"Adelaide",
    				  "snmp_poll":"off",
    				  "ping_poll":"on",
    				  "id":433
    				}
                ]
             }
          ]
       }
    }
    
    [top]

    Example: Requesting Ping Metrics for a Device

    Return ping times for the last 15 minutes as well as the average ping trip time for that period.

    cURLPythonRubyResponse
    
    curl \
    	-H "Accept: application/json" \
    	-H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    	-X GET \
    	"https://your.statseeker.server/api/v2.1/cdt_device/cdt_device/<DEVICE ID>?fields=name,ping_rtt&ping_rtt_formats=avg,vals&ping_rtt_timefilter=range%3Dnow%20-%2015m%20TO%20now%20-1m" 
    
    
    
    
    # import requests for handling connection and encoding
    import requests, json
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.get(url, headers=headers, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/cdt_device/<DEVICE ID>'
    # specify fields to be returned
    query += '/?fields=name,ping_rtt'
    # specify data formats
    query += '&ping_rtt_formats=avg,vals'
    # Filters
    query += '&ping_rtt_timefilter=range%3Dnow%20-%2015m%20TO%20now%20-1m'
    # optional response formatting
    query += '&indent=3&links=none'
    # Run the request
    resp = do_request(server, query, user, pword)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword)
    	headers = {
    		:content_type => "json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :get,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false
    	)
    end
    
    def do_request(server, query, user, pword)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword)
        else
            # Authentication successful
            headers = {
    			:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
                :method => :get,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/cdt_device/<DEVICE ID>'
    # specify fields to be returned
    $query += '/?fields=name,ping_rtt'
    # specify data formats
    $query += '&ping_rtt_formats=avg,vals'
    # Filters
    $query += '&ping_rtt_timefilter=range%3Dnow%20-%2015m%20TO%20now%20-1m'
    # optional response formatting
    $query += '&indent=3&links=none'
    # Run the request
    resp = do_request($server, $query, $user, $pword)
    puts "#{resp.to_str}"
    
    
    
    
    {
       "version":"2.1",
       "revision":"11",
       "info":"The Statseeker RESTful API",
       "data":{
          "success":true,
          "errmsg":"ok",
          "time":1623648677,
          "objects":[
             {
                "type":"cdt_device",
                "sequence":1,
                "status":{
                   "success":true,
                   "errcode":0
                },
                "data_total":1,
                "data":[
                   {
                      "name":"Houston-rtr",
                      "ping_rtt":{
                         "vals":[
                            23,
                            28,
                            30,
                            26,
                            32,
                            21,
                            28,
                            27,
                            26,
                            25,
                            30,
                            27,
                            30,
                            27
                         ],
                         "avg":27.1429
                      },
                      "id":<DEVICE ID>
                   }
                ]
             }
          ]
       }
    }
    
    [top]

    Example: Return Ping Availability Percentage for a group of devices, during business hours last month

    Show the ping availability for each device in a specified group during business hours (6am - 6pm) over the previous month

    cURLPythonRubyResponse
    
    curl \
    	-H "Accept: application/json" \
    	-H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    	-X GET \
    	"https://your.statseeker.server/api/v2.1/cdt_device?fields=name,ipaddress,ping_state&ping_state_formats=avl_inPercent&ping_state_filter_format=state&ping_state_timefilter=range=start_of_last_month%20to%20end_of_last_month;%20time%20=%2006:00%20to%2018:00;&ping_state_states=up&groups=<GROUP NAME>&links=none&indent=3" 
    
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.get(url, headers=headers, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/cdt_device'
    # specify fields to be returned
    query += '/?fields=name,ipaddress,ping_state'
    # specify data formats
    query += '&ping_state_formats=avl_inPercent'
    # Filters
    query += '&ping_state_filter_format=state&ping_state_states=up&groups=<GROUP NAME>&ping_state_timefilter=range=start_of_last_month to end_of_last_month;time = 06:00 to 18:00;'
    # optional response formatting
    query += '&indent=3&links=none'
    # Run the request
    resp = do_request(server, query, user, pword)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword)
    	headers = {
    		:content_type => "json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :get,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false
    	)
    end
    
    def do_request(server, query, user, pword)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword)
        else
            # Authentication successful
            headers = {
    			:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
                :method => :get,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/cdt_device/'
    # specify fields to be returned
    $query += '/?fields=name,ipaddress,ping_state'
    # specify data formats
    $query += '&ping_state_formats=avl_inPercent'
    # Filters
    $query += '&ping_state_filter_format=state&ping_state_states=up&groups=<GROUP NAME>&ping_state_timefilter=range=start_of_last_month to end_of_last_month; time = 06:00 to 18:00;'
    # optional response formatting
    $query += '&indent=3&links=none'
    # Run the request
    resp = do_request($server, $query, $user, $pword)
    puts "#{resp.to_str}"
    
    
    
    {
        "version": "2.1",
        "revision": "13",
        "info": "The Statseeker RESTful API",
        "data": {
            "success": true,
            "errmsg": "ok",
            "time": 1615862113,
            "objects": [
                {
                    "type": "cdt_device",
                    "sequence": 307,
                    "status": {
                        "success": true,
                        "errcode": 0
                    },
                    "data_total": 59,
                    "data": [
                        {
                            "name": "NewYork-rtr",
                            "ipaddress": "10.100.44.254",
                            "ping_state": {
                                "avl_inPercent": 93.4969
                            },
                            "id": 175
                        },
                        {
                            "name": "Chicago-rtr",
                            "ipaddress": "10.100.46.254",
                            "ping_state": {
                                "avl_inPercent": 98.1472
                            },
                            "id": 195
                        },
                        {
                            "name": "Rome-rtr",
                            "ipaddress": "10.100.52.254",
                            "ping_state": {
                                "avl_inPercent": 96.6486
                            },
                            "id": 247
                        },
                        {
                            "name": "Paris-rtr",
                            "ipaddress": "10.100.53.254",
                            "ping_state": {
                                "avl_inPercent": 96.6329
                            },
                            "id": 260
                        },
                        {
                            "name": "Barcelona-rtr",
                            "ipaddress": "10.100.54.254",
                            "ping_state": {
                                "avl_inPercent": 97.481
                            },
                            "id": 269
                        },
                        {
                            "name": "Hamburg-rtr",
                            "ipaddress": "10.100.55.254",
                            "ping_state": {
                                "avl_inPercent": 97.6203
                            },
                            "id": 276
                        },
                        {
                            "name": "Budapest-rtr",
                            "ipaddress": "10.100.56.254",
                            "ping_state": {
                                "avl_inPercent": 91.905
                            },
                            "id": 284
                        },
                        {
                            "name": "Warsaw-rtr",
                            "ipaddress": "10.100.57.254",
                            "ping_state": {
                                "avl_inPercent": 97.7061
                            },
                            "id": 292
                        },
                        {
                            "name": "Istanbul-rtr",
                            "ipaddress": "10.100.61.254",
                            "ping_state": {
                                "avl_inPercent": 96.1347
                            },
                            "id": 313
                        },
                        {
                            "name": "Helsinki-rtr",
                            "ipaddress": "10.100.62.254",
                            "ping_state": {
                                "avl_inPercent": 96.4435
                            },
                            "id": 320
                        },
                        {
                            "name": "Lisbon-rtr",
                            "ipaddress": "10.100.64.254",
                            "ping_state": {
                                "avl_inPercent": 98.4008
                            },
                            "id": 331
                        },
                        {
                            "name": "Copenhagen-rtr",
                            "ipaddress": "10.100.66.254",
                            "ping_state": {
                                "avl_inPercent": 96.6578
                            },
                            "id": 341
                        },
                        {
                            "name": "Zurich-rtr",
                            "ipaddress": "10.100.67.254",
                            "ping_state": {
                                "avl_inPercent": 97.0897
                            },
                            "id": 346
                        },
                        {
                            "name": "Auckland-rtr",
                            "ipaddress": "10.100.68.254",
                            "ping_state": {
                                "avl_inPercent": 97.4721
                            },
                            "id": 350
                        },
                        {
                            "name": "Wellington-rtr",
                            "ipaddress": "10.100.69.254",
                            "ping_state": {
                                "avl_inPercent": 96.656
                            },
                            "id": 353
                        },
                        {
                            "name": "Shanghai-rtr",
                            "ipaddress": "10.100.71.254",
                            "ping_state": {
                                "avl_inPercent": 97.1329
                            },
                            "id": 358
                        },
                        {
                            "name": "Taipei-rtr",
                            "ipaddress": "10.100.72.254",
                            "ping_state": {
                                "avl_inPercent": 95.4515
                            },
                            "id": 361
                        },
                        {
                            "name": "Tokyo-rtr",
                            "ipaddress": "10.100.73.254",
                            "ping_state": {
                                "avl_inPercent": 96.988
                            },
                            "id": 364
                        },
                        {
                            "name": "Singapore-rtr",
                            "ipaddress": "10.100.75.254",
                            "ping_state": {
                                "avl_inPercent": 96.3195
                            },
                            "id": 370
                        },
                        {
                            "name": "Jakarta-rtr",
                            "ipaddress": "10.100.76.254",
                            "ping_state": {
                                "avl_inPercent": 96.5654
                            },
                            "id": 373
                        },
                        {
                            "name": "Manila-rtr",
                            "ipaddress": "10.100.77.254",
                            "ping_state": {
                                "avl_inPercent": 95.6723
                            },
                            "id": 378
                        },
                        {
                            "name": "KualaLumpur-rtr",
                            "ipaddress": "10.100.78.254",
                            "ping_state": {
                                "avl_inPercent": 96.1833
                            },
                            "id": 381
                        },
                        {
                            "name": "Delhi-rtr",
                            "ipaddress": "10.100.80.254",
                            "ping_state": {
                                "avl_inPercent": 97.6462
                            },
                            "id": 387
                        },
                        {
                            "name": "Mumbai-rtr",
                            "ipaddress": "10.100.81.254",
                            "ping_state": {
                                "avl_inPercent": 96.5621
                            },
                            "id": 390
                        },
                        {
                            "name": "Bangalore-rtr",
                            "ipaddress": "10.100.82.254",
                            "ping_state": {
                                "avl_inPercent": 93.9592
                            },
                            "id": 393
                        },
                        {
                            "name": "Chennai-rtr",
                            "ipaddress": "10.100.84.254",
                            "ping_state": {
                                "avl_inPercent": 94.9474
                            },
                            "id": 399
                        },
                        {
                            "name": "Brisbane-rtr",
                            "ipaddress": "10.100.86.254",
                            "ping_state": {
                                "avl_inPercent": 95.2075
                            },
                            "id": 405
                        },
                        {
                            "name": "Melbourne-rtr",
                            "ipaddress": "10.100.87.254",
                            "ping_state": {
                                "avl_inPercent": 96.4931
                            },
                            "id": 408
                        },
                        {
                            "name": "Perth-rtr",
                            "ipaddress": "10.100.88.254",
                            "ping_state": {
                                "avl_inPercent": 95.4568
                            },
                            "id": 411
                        },
                        {
                            "name": "Cairo-rtr",
                            "ipaddress": "10.100.90.254",
                            "ping_state": {
                                "avl_inPercent": 95.8718
                            },
                            "id": 417
                        },
                        {
                            "name": "Johannesburg-rtr",
                            "ipaddress": "10.100.91.254",
                            "ping_state": {
                                "avl_inPercent": 93.7854
                            },
                            "id": 420
                        },
                        {
                            "name": "PortElizabeth-rtr",
                            "ipaddress": "10.100.93.254",
                            "ping_state": {
                                "avl_inPercent": 94.4832
                            },
                            "id": 426
                        },
                        {
                            "name": "Pretoria-rtr",
                            "ipaddress": "10.100.94.254",
                            "ping_state": {
                                "avl_inPercent": 95.6376
                            },
                            "id": 432
                        },
                        {
                            "name": "LosAngeles-rtr",
                            "ipaddress": "10.100.45.254",
                            "ping_state": {
                                "avl_inPercent": 97.3842
                            },
                            "id": 21115
                        },
                        {
                            "name": "Athens-rtr",
                            "ipaddress": "10.100.59.254",
                            "ping_state": {
                                "avl_inPercent": 94.7204
                            },
                            "id": 21118
                        },
                        {
                            "name": "Dublin-rtr",
                            "ipaddress": "10.100.65.254",
                            "ping_state": {
                                "avl_inPercent": 96.4443
                            },
                            "id": 21121
                        },
                        {
                            "name": "Beijing-rtr",
                            "ipaddress": "10.100.70.254",
                            "ping_state": {
                                "avl_inPercent": 96.2173
                            },
                            "id": 21122
                        },
                        {
                            "name": "Houston-rtr",
                            "ipaddress": "10.100.47.254",
                            "ping_state": {
                                "avl_inPercent": 97.7115
                            },
                            "id": 26477
                        },
                        {
                            "name": "London-rtr",
                            "ipaddress": "10.100.49.254",
                            "ping_state": {
                                "avl_inPercent": 97.5155
                            },
                            "id": 26478
                        },
                        {
                            "name": "CapeTown-rtr",
                            "ipaddress": "10.100.92.254",
                            "ping_state": {
                                "avl_inPercent": 95.6713
                            },
                            "id": 26480
                        },
                        {
                            "name": "Kolkata-rtr",
                            "ipaddress": "10.100.83.254",
                            "ping_state": {
                                "avl_inPercent": 95.9105
                            },
                            "id": 54838
                        },
                        {
                            "name": "Adelaide-rtr",
                            "ipaddress": "10.100.89.254",
                            "ping_state": {
                                "avl_inPercent": 96.9231
                            },
                            "id": 55175
                        },
                        {
                            "name": "Berlin-rtr",
                            "ipaddress": "10.119.50.254",
                            "ping_state": {
                                "avl_inPercent": 96.1095
                            },
                            "id": 90353
                        },
                        {
                            "name": "Madrid-rtr",
                            "ipaddress": "10.119.51.254",
                            "ping_state": {
                                "avl_inPercent": 94.8712
                            },
                            "id": 90357
                        },
                        {
                            "name": "Vienna-rtr",
                            "ipaddress": "10.119.58.254",
                            "ping_state": {
                                "avl_inPercent": 96.621
                            },
                            "id": 90419
                        },
                        {
                            "name": "Stockholm-rtr",
                            "ipaddress": "10.119.63.254",
                            "ping_state": {
                                "avl_inPercent": 94.0744
                            },
                            "id": 90448
                        },
                        {
                            "name": "Bangkok-rtr",
                            "ipaddress": "10.119.79.254",
                            "ping_state": {
                                "avl_inPercent": 94.4871
                            },
                            "id": 90506
                        },
                        {
                            "name": "Phoenix-rtr",
                            "ipaddress": "10.100.48.254",
                            "ping_state": {
                                "avl_inPercent": 93.6085
                            },
                            "id": 158201
                        },
                        {
                            "name": "Seoul-rtr",
                            "ipaddress": "10.100.74.254",
                            "ping_state": {
                                "avl_inPercent": 93.8363
                            },
                            "id": 209909
                        },
                        {
                            "name": "Sydney-rtr",
                            "ipaddress": "10.100.85.254",
                            "ping_state": {
                                "avl_inPercent": 96.3044
                            },
                            "id": 209912
                        }
                    ]
                }
            ]
        }
    }
    
    [top]

    Example: Deleting Multiple Devices via IP Address

    Delete multiple devices in a single call by filter the device list by ipaddress.

    We will delete devices with ipaddress = 10.100.59.251, 10.100.59.251.

    cURLPythonRubyResponse
    
    curl \
    	-H "Accept: application/json" \
    	-H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    	-X DELETE \
    	"https://your.statseeker.server/api/v2.1/cdt_device/cdt_device/" 
    	-d '{"fields":{"ipaddress":{"field":"ipaddress","filter":{"query":"IN(\"<IP ADDRESS 1>",\"<IP ADDRESS 2>\")"}}}}'
    	
    
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword, reqData):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.delete(url, headers=headers, data=reqData, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.delete(url, headers=headers, auth=(user, pword), data=reqData, verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/cdt_device'
    # optional response formatting
    query += '/?indent=3&links=none'
    # data
    reqData = json.dumps({"fields":{"ipaddress":{"field":"ipaddress","filter":{"query":"IN(\"<IP ADDRESS 1>\",\"<IP ADDRESS 2>\")"}}}})
    # Run the request
    resp = do_request(server, query, user, pword, reqData)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword, reqData)
    	headers = {
    		:content_type => "application/json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :delete,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false,
    		:payload => reqData
    	)
    end
    
    def do_request(server, query, user, pword, reqData)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword, reqData)
        else		
            # Authentication successful
    		headers = {
    		:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
    			:method => :delete,
    			:url => url,
    			:headers => headers,
    			:verify_ssl => false,
    			:payload => reqData
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword, reqData)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/cdt_device'
    # optional response formatting
    $query += '/?indent=3&links=none'
    # configure payload
    $reqData = '{"fields":{"ipaddress":{"field":"ipaddress","filter":{"query":"IN(\'<IP ADDRESS 1>\',\'<IP ADDRESS 2>\')"}}}}'
    # Run the request
    resp = do_request($server, $query, $user, $pword, $reqData)
    puts "#{resp.to_str}"
    
    
    
    
    {
       "version":"2.1",
       "revision":"11",
       "info":"The Statseeker RESTful API",
       "data":{
          "success":true,
          "errmsg":"ok",
          "time":1623649404
       }
    }
    
    [top]

    Interface (cdt_port)

    The cdt_port resource allows you to interact with the network interfaces being monitored by Statseeker.

    The cdt_port object
    Field ID Field Title Type Get, Add, Update Description
    id ID integer G The entity identifier
    name Name string G The entity name
    deviceid Device ID integer G The ID of the parent device
    idx Index string G The base SNMP index for this entity
    table Table string G The table to which the entity belongs
    poll Poll State string G, U The poll state of the entity

    • on
    • off
    InBroadcastPkts Rx Bcast Pkts integer G Number of received broadcast packets
    Timeseries Data: Stats, Formats & Options
    InBroadcastPps Rx Bcast Pps float G Number of received broadcast packets per second
    Timeseries Data: Stats, Formats & Options
    InDiscards Rx Discards integer G Number of received discards
    Timeseries Data: Stats, Formats & Options
    InErrors Rx Errors integer G Number of received errors
    Timeseries Data: Stats, Formats & Options
    InMulticastPkts Rx Mcast Pkts integer G Number of received multicast packets
    Timeseries Data: Stats, Formats & Options
    InMulticastPps Rx Mcast Pps float G Number of received multicast packets per second
    Timeseries Data: Stats, Formats & Options
    InOctets Rx Bytes integer G Number of received bytes
    Timeseries Data: Stats, Formats & Options
    InOutBroadcastPkts Total Bcast Pkts integer G Combined Rx and Tx broadcast packets
    Timeseries Data: Stats, Formats & Options
    InOutDiscards Total Discards integer G Combined Rx and Tx Discards
    Timeseries Data: Stats, Formats & Options
    InOutErrors Total Errors integer G Combined Rx and Tx Errors
    Timeseries Data: Stats, Formats & Options
    InOutMulticastPkts Total Mcast Pkts integer G Combined Rx and Tx multicast packets
    Timeseries Data: Stats, Formats & Options
    InOutOctets Total Bytes integer G Combined Rx and Tx Bytes
    Timeseries Data: Stats, Formats & Options
    InOutSpeed Total Speed integer G Combined Rx and Tx Speed
    InOutUcastPkts Total Ucast Pkts integer G Combined Rx and Tx unicast packets
    Timeseries Data: Stats, Formats & Options
    InUcastPkts Rx Ucast Pkts integer G Number of received unicast packets
    Timeseries Data: Stats, Formats & Options
    InUcastPps Rx Ucast Pps float G Number of received unicast packets per second
    Timeseries Data: Stats, Formats & Options
    OutBroadcastPkts Tx Bcast Pkts integer G Number of transmitted broadcast packets
    Timeseries Data: Stats, Formats & Options
    OutBroadcastPps Tx Bcast Pps float G Number of transmitted broadcast packets per second
    Timeseries Data: Stats, Formats & Options
    OutDiscards Tx Discards integer G Number of transmitted discards
    Timeseries Data: Stats, Formats & Options
    OutErrors Tx Errors integer G Number of transmitted errors
    Timeseries Data: Stats, Formats & Options
    OutMulticastPkts Tx Mcast Pkts integer G Number of transmitted multicast packets
    Timeseries Data: Stats, Formats & Options
    OutMulticastPps Tx Mcast Pps float G Number of transmitted multicast packets per second
    Timeseries Data: Stats, Formats & Options
    OutOctets Tx Bytes integer G Number of transmitted bytes
    Timeseries Data: Stats, Formats & Options
    OutUcastPkts Tx Ucast Pkts integer G Number of transmitted unicast packets
    Timeseries Data: Stats, Formats & Options
    OutUcastPps Tx Ucast Pps float G Number of transmitted unicast packets per second
    Timeseries Data: Stats, Formats & Options
    RxBps Rx Bps float G Received bits per second
    Timeseries Data: Stats, Formats & Options
    RxDiscardsPercent Rx Discards Percent float G Rx discards percentage
    Timeseries Data: Stats, Formats & Options
    RxErrorPercent Rx Errors Percent float G Rx errors percentage
    Timeseries Data: Stats, Formats & Options
    RxTxDiscardsPercent Total Discards Percent float G Total discards percentage
    Timeseries Data: Stats, Formats & Options
    RxTxErrorPercent Total Errors Percent float G Total errors percentage
    Timeseries Data: Stats, Formats & Options
    RxUtil Rx Util float G Rx Utilization
    Timeseries Data: Stats, Formats & Options
    TxBps Tx Bps float G Transmitted bits per second
    Timeseries Data: Stats, Formats & Options
    TxDiscardsPercent Tx Discards Percent float G Tx discards percentage
    Timeseries Data: Stats, Formats & Options
    TxErrorPercent Tx Errors Percent float G Tx errors percentage
    Timeseries Data: Stats, Formats & Options
    TxUtil Tx Util float G Tx Utilization
    Timeseries Data: Stats, Formats & Options
    if90day if90day integer G, U Status of port usage over 90 days, one of:

    • 0
    • 1
    ifAdminStatus ifAdminStatus string G, U The desired state of the interface, one of:

    • up
    • down
    • testing

    Can be combined with an event format for event-based analytics, see Event Formats.

    ifAlias Alias string G, U Interface Alias (ifAlias)
    ifDescr Description string G, U Interface Description (ifDescr)
    ifDuplex ifDuplex string G, U Interface Duplex, one of:

    • auto
    • half
    • full
    • unknown
    ifInSpeed Rx Speed integer G, U Interface Input Speed (Statseeker custom attribute)
    ifIndex ifIndex string G, U Interface Index (IF-MIB.ifIndex)
    ifName ifName string G, U Interface Name (IF-MIB.ifName)
    ifNonUnicast NUcast Polling string G, U NonUnicast Polling status of the port, one of:

    • on
    • off
    • global
    ifOperStatus ifOperStatus string G, U Current operational status of port, one of:

    • dormant
    • down
    • lowerLayerDown
    • notPresent
    • testing
    • unknown
    • up

    Can be combined with an event format for event-based analytics, see Event Formats.

    ifOutSpeed Tx Speed integer G, U Interface Output Speed (Statseeker custom attribute)
    ifPhysAddress PhysAddress string G, U Interface MAC Address (ifPhysAddress)
    ifPoll ifPoll string G, U Polling status of the port, one of:

    • on
    • off
    ifSpeed Speed integer G, U Interface Speed (based on ifSpeed or ifHighSpeed)
    ifTitle Title string G, U Interface Title (Statseeker custom attribute - ifTitle)
    ifType Type string G, U Interface Type, one of:

    • a12MppSwitch
    • aal2
    • aal5
    • actelisMetaLOOP
    • adsl
    • adsl2
    • adsl2plus
    • aflane8023
    • aflane8025
    • arap
    • arcnet
    • arcnetPlus
    • async
    • atm
    • atmbond
    • atmDxi
    • atmFuni
    • atmIma
    • atmLogical
    • atmRadio
    • atmSubInterface
    • atmVciEndPt
    • atmVirtual
    • aviciOpticalEther
    • basicISDN
    • bgppolicyaccounting
    • bridge
    • bsc
    • cblVectaStar
    • cctEmul
    • ces
    • channel
    • ciscoISLvlan
    • cnr
    • coffee
    • compositeLink
    • dcn
    • ddnX25
    • digitalPowerline
    • digitalWrapperOverheadChannel
    • dlsw
    • docsCableDownstream
    • docsCableMaclayer
    • docsCableMCmtsDownstream
    • docsCableUpstream
    • docsCableUpstreamChannel
    • ds0
    • ds0Bundle
    • ds1
    • ds1FDL
    • ds3
    • dtm
    • dvbAsiIn
    • dvbAsiOut
    • dvbRccDownstream
    • dvbRccMacLayer
    • dvbRccUpstream
    • e1
    • econet
    • eon
    • eplrs
    • escon
    • ethernet3Mbit
    • ethernetCsmacd
    • fast
    • fastEther
    • fastEtherFX
    • fcipLink
    • fddi
    • fibreChannel
    • frameRelay
    • frameRelayInterconnect
    • frameRelayMPI
    • frameRelayService
    • frDlciEndPt
    • frf16MfrBundle
    • frForward
    • g703at2mb
    • g703at64k
    • gfp
    • gigabitEthernet
    • gr303IDT
    • gr303RDT
    • gtp
    • h323Gatekeeper
    • h323Proxy
    • hdh1822
    • hdlc
    • hdsl2
    • hiperlan2
    • hippi
    • hippiInterface
    • homepna
    • hostPad
    • hssi
    • hyperchannel
    • ibm370parChan
    • idsl
    • ieee1394
    • ieee80211
    • ieee80212
    • ieee80216WMAN
    • ieee8023adLag
    • if-gsn
    • imt
    • infiniband
    • interleave
    • ip
    • ipForward
    • ipOverAtm
    • ipOverCdlc
    • ipOverClaw
    • ipSwitch
    • isdn
    • isdns
    • isdnu
    • iso88022llc
    • iso88023Csmacd
    • iso88024TokenBus
    • iso88025CRFPInt
    • iso88025Dtr
    • iso88025Fiber
    • iso88025TokenRing
    • iso88026Man
    • isup
    • l2vlan
    • l3ipvlan
    • l3ipxvlan
    • lapb
    • lapd
    • lapf
    • linegroup
    • lmp
    • localTalk
    • macSecControlledIF
    • macSecUncontrolledIF
    • mediaMailOverIp
    • mfSigLink
    • miox25
    • mocaVersion1
    • modem
    • mpc
    • mpegTransport
    • mpls
    • mplsTunnel
    • msdsl
    • mvl
    • myrinet
    • nfas
    • nsip
    • opticalChannel
    • opticalChannelGroup
    • opticalTransport
    • other
    • para
    • pdnEtherLoop1
    • pdnEtherLoop2
    • plc
    • pon155
    • pon622
    • pos
    • ppp
    • pppMultilinkBundle
    • primaryISDN
    • propAtm
    • propBWAp2Mp
    • propCnls
    • propDocsWirelessDownstream
    • propDocsWirelessMaclayer
    • propDocsWirelessUpstream
    • propMultiplexor
    • propPointToPointSerial
    • propVirtual
    • propWirelessP2P
    • proteon10Mbit
    • proteon80Mbit
    • q2931
    • qam
    • qllc
    • radioMAC
    • radsl
    • reachDSL
    • regular1822
    • rfc1483
    • rfc877x25
    • rpr
    • rs232
    • rsrb
    • sdlc
    • sdsl
    • shdsl
    • sip
    • sipSig
    • sipTg
    • sixToFour
    • slip
    • smdsDxi
    • smdsIcip
    • softwareLoopback
    • sonet
    • sonetOverheadChannel
    • sonetPath
    • sonetVT
    • srp
    • ss7SigLink
    • stackToStack
    • starLan
    • tdlc
    • teLink
    • termPad
    • tr008
    • trasnpHdlc
    • tunnel
    • ultra
    • usb
    • v11
    • v35
    • v36
    • v37
    • vdsl
    • virtualIpAddress
    • virtualTg
    • voiceDID
    • voiceEM
    • voiceEMFGD
    • voiceEncap
    • voiceFGDEANA
    • voiceFGDOS
    • voiceFXO
    • voiceFXS
    • voiceOverAtm
    • voiceOverCable
    • voiceOverFrameRelay
    • voiceOverIp
    • x213
    • x25huntGroup
    • x25mlp
    • x25ple
    Links

    This resource has links to the following:

    [top]

    Example: Turning Off an Interface

    In this example we will use the device and interface name to identify the interface and then update the polling status on the selected interface.

    • Start with a device name and an interface name, Use these to get the interface ID
    • Use the interface ID to update the polling status of the interface
    cURLPythonRubyResponse
    
    curl \
        -H "Accept: application/json" \
        -H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
        -X GET \
    	"https://your.statseeker.server/api/v2.1/cdt_port/?fields=name,cdt_device.name&name_filter=IS(%27<INTERFACE NAME>%27)&cdt_device.name_filter=IS(%27<DEVICE NAME>%27)&indent=3&links=none"
    	
    	
    curl \
        -H "Accept: application/json" \
        -H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
        -X PUT \
    	"https://your.statseeker.server/api/v2.1/cdt_port/<INTERFACE ID>/?indent=3"
        -d '{"data":[{%27poll%27:%27off%27}]}'
    	
    
    # import requests for handling connection and encoding
    import requests
    import json
    
    def do_request(server, query, user, pword, reqType, reqData):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            if reqType == "get":
                resp = requests.get(url, headers=headers, verify=False)
            else:
                resp = requests.put(url, headers=headers, data=reqData, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            if reqType == "get":
                resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
            else:
                resp = requests.put(url, headers=headers, auth=(user, pword), data=reqData, verify=False)        
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/cdt_port'
    # specify fields to be returned
    query += '/?fields=name,cdt_device.name'
    # Filters
    query += '&name_filter=IS("<INTERFACE NAME>")&cdt_device.name_filter=IS("<DEVICE NAME>")'
    # optional response formatting
    query += '&indent=3&links=none'
    # set request type
    reqType = 'get'
    data=''
    portId=''
    
    # Run the request
    resp = do_request(server, query, user, pword, reqType, data)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
        portId=str(resp.json()['data']['objects'][0]['data'][0]['id'])
        print("Interface ID: " + portId)
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    # build next query
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/cdt_port/' + portId
    # optional response formatting
    query += '/?indent=3&links=none'
    # update poll status to turn off polling
    data = json.dumps({"data":[{"poll":"off"}]})
    # set request type
    reqType = 'put'
    # Run the request
    resp = do_request(server, query, user, pword, reqType, data)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword, reqType, reqData)
    	headers = {
    		:content_type => "json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => reqType,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false,
    		:payload => reqData
    	)
    end
    
    def do_request(server, query, user, pword, reqType, reqData)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword, reqType, reqData)
        else
            # Authentication successful
            headers = {
    			:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
                :method => reqType,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
    			:payload => reqData
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword, reqType, reqData)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/cdt_port'
    # specify fields to be returned
    $query += '/?fields=name,cdt_device.name'
    # Filters
    $query += '&name_filter=IS("<INTERFACE NAME>")&cdt_device.name_filter=IS("<DEVICE NAME>")'
    # optional response formatting
    $query += '&indent=3&links=none'
    $reqData = ''
    # Set request type
    $reqType = 'get'
    # Run the request
    resp = do_request($server, $query, $user, $pword, $reqType, $reqData)
    puts "#{resp.to_str}"
    rData = JSON.parse(resp)
    $p = rData['data']['objects'][0]['data'][0]['id']
    
    # output interface ID to screen
    puts "#{'interfaceID: ' + $p.to_s}"
    
    # build next query
    # API root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/cdt_port/' + $p.to_s
    # specify fields to be returned
    $query += '/?indent=3&links=none'
    # update poll status to turn off polling
    $reqData = '{"data":[{"poll":"off"}]}'
    # set request type
    $reqType = 'put'
    # Run the request
    resp = do_request($server, $query, $user, $pword, $reqType, $reqData)
    puts "#{resp.to_str}"
    
    
    
    #This response includes some logging (preceding the response data object) which is only relevant to the Python and Ruby implementations
    200
    {
       "version":"2.1",
       "revision":"11",
       "info":"The Statseeker RESTful API",
       "data":{
          "success":true,
          "errmsg":"ok",
          "time":1623655171,
          "objects":[
             {
                "type":"cdt_port",
                "sequence":5,
                "status":{
                   "success":true,
                   "errcode":0
                },
                "data_total":1,
                "data":[
                   {
                      "name":"<INTERFACE NAME>",
                      "cdt_device.name":"<DEVICE NAME>",
                      "id":<INTERFACE ID>"
                   }
                ]
             }
          ]
       }
    }
    "Interface ID":<INTERFACE ID>"
    200
    {
       "version":"2.1",
       "revision":"11",
       "info":"The Statseeker RESTful API",
       "data":{
          "success":true,
          "errmsg":"ok",
          "time":1623655172
       }
    }
    
    
    [top]

    Example: Requesting Timeseries Data from all Interfaces on a Device

    Request:

    • Identifying data: the name and ID of the interface
    • Timeseries data: total inbound/outbound discard percentage for the reporting period, minimum, average, and 95th percentile values for inbound/outbound utilization
    • Time filter of 'start of the day until now'
    • Sort results on the average inbound utilization, descending
    • Filter the results to show only those interfaces on a specific device
    cURLPythonRubyResponse
    
    curl \
        -H "Accept: application/json" \
        -H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
        -X GET \
    	"https://your.statseeker.server/api/v2.1/cdt_port/?fields=deviceid,id,name,RxTxDiscardsPercent,TxUtil,RxUtil&RxUtil_sort=1,desc,avg&deviceid_filter=IS(%22<DEVICE ID>%22)&RxUtil_formats=95th,avg,min&TxUtil_formats=95th,avg,min&RxTxDiscardsPercent_formats=total&timefilter=range=start_of_today%20to%20now"
    	
    	
    	
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.get(url, headers=headers, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/cdt_port'
    # specify fields to be returned
    query += '/?fields=deviceid,id,name,RxTxDiscardsPercent,TxUtil,RxUtil'
    # specify data formats
    query += '&formats=95th,avg,min&RxTxDiscardsPercent_formats=total'
    # specify filters
    query += '&deviceid_filter=IS("<DEVICE ID>")&timefilter=range=start_of_today to now'
    # optional response formatting
    query += '&indent=3&links=none'
    # Run the request
    resp = do_request(server, query, user, pword)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword)
    	headers = {
    		:content_type => "json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :get,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false
    	)
    end
    
    def do_request(server, query, user, pword)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword)
        else
            # Authentication successful
            headers = {
    			:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
                :method => :get,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/cdt_port'
    # specify fields to be returned
    $query += '/?fields=deviceid,id,name,RxTxDiscardsPercent,TxUtil,RxUtil'
    # specify data formats
    $query += '&formats=95th,avg,min&RxTxDiscardsPercent_formats=total'
    # Filters
    $query += '&timefilter=range=start_of_today to now&deviceid_filter=IS('<DEVICE ID>')'
    # optional response formatting
    $query += '&indent=3&links=none'
    # Run the request
    resp = do_request($server, $query, $user, $pword)
    puts "#{resp.to_str}"
    
    
    
    {
    
        'version':'2.1',
        'revision':'11',
        'info':'The Statseeker RESTful API',
        'data':{
            'success':True,
            'errmsg':'ok',
            'time':1623714662,
            'objects':[
                {
                    'type':'cdt_port',
                    'sequence':11,
                    'status':{
                        'success':True,
                        'errcode':0
                    },
                    'data_total':5,
                    'data':[
                        {
                            'deviceid':<DEVICE ID>,
                            'id':5267,
                            'name':'Gi0/1',
                            'RxTxDiscardsPercent':{
                                'total':0
                            },
                            'TxUtil':{
                                'min':1.40207,
                                'avg':1.88639,
                                '95th':2.19703
                            },
                            'RxUtil':{
                                'min':1.27934,
                                'avg':1.87145,
                                '95th':2.11322
                            }
                        },
                        {
                            'deviceid':<DEVICE ID>,
                            'id':5268,
                            'name':'Gi0/2',
                            'RxTxDiscardsPercent':{
                                'total':0
                            },
                            'TxUtil':{
                                'min':1.20236,
                                'avg':1.9108,
                                '95th':2.26653
                            },
                            'RxUtil':{
                                'min':1.52055,
                                'avg':1.8971,
                                '95th':2.14601
                            }
                        },
                        {
                            'deviceid':<DEVICE ID>,
                            'id':5269,
                            'name':'Gi0/3',
                            'RxTxDiscardsPercent':{
                                'total':0.00919672
                            },
                            'TxUtil':{
                                'min':9.02538,
                                'avg':32.583,
                                '95th':71.7206
                            },
                            'RxUtil':{
                                'min':9.19671,
                                'avg':45.9247,
                                '95th':71.0976
                            }
                        },
                        {
                            'deviceid':<DEVICE ID>,
                            'id':5270,
                            'name':'Gi0/4',
                            'RxTxDiscardsPercent':{
                                'total':0
                            },
                            'TxUtil':{
                                'min':1.19819,
                                'avg':25.2168,
                                '95th':37.0137
                            },
                            'RxUtil':{
                                'min':0.948108,
                                'avg':23.3934,
                                '95th':37.0401
                            }
                        },
                        {
                            'deviceid':<DEVICE ID>,
                            'id':5271,
                            'name':'Gi0/5',
                            'RxTxDiscardsPercent':{
                                'total':0
                            },
                            'TxUtil':{
                                'min':0.833396,
                                'avg':0.933941,
                                '95th':0.950772
                            },
                            'RxUtil':{
                                'min':0.833468,
                                'avg':0.933937,
                                '95th':0.950873
                            }
                        }
                    ]
                }
            ]
        }
    
    }
    
    [top]

    Example: Return the 10 Most Congested Interfaces (inbound) over the Last 30mins
    cURLPythonRubyResponse
    
    curl \
        -H "Accept: application/json" \
        -H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
        -X GET \
        'https://your.statseeker.server/api/v2.1/cdt_port/?fields=deviceid,id,name,RxUtil&RxUtil_formats=vals,avg&RxUtil_timefilter=range=now%20-%2030m%20to%20now%20-%201m&RxUtil_sort=1,desc,avg&limit=10&indent=3'	
    
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.get(url, headers=headers, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/cdt_port'
    # specify fields to be returned
    query += '/?fields=deviceid,id,name,RxUtil'
    # specify data formats
    query += '&RxUtil_formats=vals,avg'
    # Filters and sorting
    query += '&RxUtil_timefilter=range=now - 30m to now - 1m&limit=10&RxUtil_sort=1,desc,avg'
    # optional response formatting
    query += '&indent=3&links=none'
    # Run the request
    resp = do_request(server, query, user, pword)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword)
    	headers = {
    		:content_type => "json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :get,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false
    	)
    end
    
    def do_request(server, query, user, pword)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword)
        else
            # Authentication successful
            headers = {
    			:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
                :method => :get,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/cdt_port'
    # specify fields to be returned
    $query += '/?fields=deviceid,id,name,RxUtil'
    # specify data formats
    $query += '&RxUtil_formats=vals,avg'
    # Filters and sorting
    $query += '&RxUtil_timefilter=range=now - 30m to now - 1m&limit=10&RxUtil_sort=1,desc,avg'
    # optional response formatting
    $query += '&indent=3&links=none'
    # Run the request
    resp = do_request($server, $query, $user, $pword)
    puts "#{resp.to_str}"
    
    
    {
       "version":"2.1",
       "revision":"11",
       "info":"The Statseeker RESTful API",
       "data":{
          "success":true,
          "errmsg":"ok",
          "time":1623715763,
          "objects":[
             {
                "type":"cdt_port",
                "sequence":11,
                "status":{
                   "success":true,
                   "errcode":0
                },
                "data_total":21178,
                "data":[
                   {
                      "deviceid":666,
                      "id":25349,
                      "name":"int.673",
                      "RxUtil":{
                         "vals":[
                            58.412,
                            59.2569,
                            62.7188,
                            62.8199,
                            60.9338,
                            61.2049,
                            62.5076,
                            64.7656,
                            68.891,
                            74.0913,
                            76.311,
                            79.5807,
                            82.8285,
                            89.1304,
                            93.4463,
                            94.0603,
                            97.8606,
                            102.481,
                            108.23,
                            108.733,
                            109.634,
                            111.784,
                            110.537,
                            118.258,
                            120.432,
                            121.998,
                            124.984,
                            131.161,
                            129.887
                         ],
                         "avg":91.2737
                      }
                   },
                   {
                      "deviceid":576,
                      "id":14508,
                      "name":"Gi2/6",
                      "RxUtil":{
                         "vals":[
                            14.7061,
                            84.3344,
                            91.9828,
                            93.1667,
                            94.9071,
                            95.082,
                            94.8615,
                            91.9828,
                            94.6667,
                            95,
                            95.1452,
                            94.8721,
                            93.4828,
                            93.3333,
                            96.3333,
                            95.2404,
                            91.9404,
                            93.1525,
                            93.3333,
                            91.8333,
                            94.8118,
                            96.3663,
                            93.6552,
                            91.8333,
                            91.6667,
                            94.8118,
                            94.8721,
                            93.4828,
                            93.3333
                         ],
                         "avg":90.8341
                      }
                   },
                   {
                      "deviceid":607,
                      "id":19079,
                      "name":"Gi5/1",
                      "RxUtil":{
                         "vals":[
                            32.9511,
                            82.6984,
                            94.9561,
                            93.7022,
                            92.1038,
                            93.1148,
                            95.8307,
                            92.4708,
                            94.5127,
                            90.6501,
                            91.9098,
                            95.467,
                            95.2381,
                            95,
                            95.0683,
                            92.6169,
                            95.4101,
                            95.1675,
                            93.6635,
                            93.4426,
                            94.8462,
                            94.8999,
                            94.8992,
                            92.2081,
                            94.4444,
                            93.8757,
                            95.8758,
                            18.9708,
                            2.16111
                         ],
                         "avg":85.7985
                      }
                   },
                   {
                      "deviceid":560,
                      "id":12370,
                      "name":"Gi4/24",
                      "RxUtil":{
                         "vals":[
                            93.6138,
                            96.0178,
                            93.7018,
                            94.878,
                            95.082,
                            95.0123,
                            94.928,
                            94.9887,
                            95,
                            91.9887,
                            94.7371,
                            94.8776,
                            96.4521,
                            95.2669,
                            94.9375,
                            82.538,
                            13.7182,
                            1.89558,
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            null
                         ],
                         "avg":84.4241
                      }
                   },
                   {
                      "deviceid":572,
                      "id":14061,
                      "name":"Gi1/16",
                      "RxUtil":{
                         "vals":[
                            94.9785,
                            94.8721,
                            91.9828,
                            93.1667,
                            94.9071,
                            95.082,
                            94.8615,
                            91.9828,
                            94.6667,
                            95,
                            95.1452,
                            94.8721,
                            94.9828,
                            93.5,
                            93.2316,
                            93.521,
                            91.7614,
                            93.1525,
                            94.8333,
                            92,
                            94.8118,
                            96.3663,
                            93.6552,
                            60.9933,
                            7.39,
                            1.83817,
                            1.91872,
                            1.8731,
                            1.86667
                         ],
                         "avg":77.2143
                      }
                   },
                   {
                      "deviceid":591,
                      "id":17044,
                      "name":"Gi6/20",
                      "RxUtil":{
                         "vals":[
                            1.87849,
                            36.1878,
                            87.6018,
                            93.6762,
                            94.8087,
                            95.082,
                            96.2094,
                            93.8999,
                            94.7404,
                            93.517,
                            93.6706,
                            95.8482,
                            95.2143,
                            95.0697,
                            95.0137,
                            92.5529,
                            95.5319,
                            95.1779,
                            93.5706,
                            93.3333,
                            94.9524,
                            94.9097,
                            96.3131,
                            95.2415,
                            93.5833,
                            22.1281,
                            3.58259,
                            1.87595,
                            1.895
                         ],
                         "avg":77.1402
                      }
                   },
                   {
                      "deviceid":92491,
                      "id":93714,
                      "name":"Gi5/21",
                      "RxUtil":{
                         "vals":[
                            75.9317,
                            76.1367,
                            75.4496,
                            74.7143,
                            74.1968,
                            75.9783,
                            76.6457,
                            76.8767,
                            76.9577,
                            76.8083,
                            76.3996,
                            76.9991,
                            77.3082,
                            76.5974,
                            75.1579,
                            74.208,
                            75.7776,
                            74.1712,
                            75.5847,
                            76.9485,
                            73.8196,
                            73.5756,
                            74.4403,
                            73.1962,
                            73.1154,
                            70.7376,
                            71.3308,
                            74.8943,
                            76.6727
                         ],
                         "avg":75.1942
                      }
                   },
                   {
                      "deviceid":468,
                      "id":7245,
                      "name":"Gi0/4",
                      "RxUtil":{
                         "vals":[
                            74.404,
                            74.1828,
                            76.5702,
                            77.0775,
                            77.3333,
                            75.5785,
                            73.5372,
                            74.079,
                            74.8937,
                            73.9347,
                            72.175,
                            73.2957,
                            72.9874,
                            76.0928,
                            76.1607,
                            74.4128,
                            74.838,
                            75.9916,
                            77.3333,
                            77.2873,
                            74.482,
                            72.616,
                            74.6077,
                            73.5125,
                            71.4153,
                            70.4813,
                            76.5989,
                            77.155,
                            74.8029
                         ],
                         "avg":74.753
                      }
                   },
                   {
                      "deviceid":542,
                      "id":11260,
                      "name":"Gi2/20",
                      "RxUtil":{
                         "vals":[
                            95.1452,
                            94.9481,
                            93.4181,
                            94.8958,
                            93.6339,
                            94.7923,
                            93.3563,
                            91.9333,
                            94.6271,
                            93.428,
                            94.9672,
                            94.8721,
                            94.9828,
                            93.5984,
                            94.7434,
                            95.1367,
                            93.3778,
                            93.3103,
                            96.3333,
                            93.6667,
                            94.9785,
                            94.9481,
                            62.6062,
                            7.5439,
                            1.87197,
                            1.89782,
                            1.86734,
                            1.83621,
                            1.89333
                         ],
                         "avg":74.2969
                      }
                   },
                   {
                      "deviceid":603,
                      "id":18345,
                      "name":"Gi3/11",
                      "RxUtil":{
                         "vals":[
                            75.2432,
                            76.9031,
                            74.3828,
                            73.5258,
                            73.8093,
                            74.4585,
                            75.7062,
                            73.6734,
                            74.6045,
                            74.9261,
                            73.7239,
                            74.2233,
                            75.8226,
                            75.2778,
                            74.8531,
                            76.0055,
                            74.3657,
                            75.7361,
                            73.3104,
                            70.7072,
                            72.137,
                            71.5355,
                            75.3817,
                            72.7648,
                            72.9251,
                            73.4308,
                            72.6468,
                            73.2978,
                            72.2705
                         ],
                         "avg":74.0568
                      }
                   }
                ]
             }
          ]
       }
    }
    
    [top]

    Example: Return the 10 Busiest Interfaces, According to their 90th Percentile Values, over the Last Hour

    We are returning the deviceid and interface name to identify the interface.

    cURLPythonRubyResponse
    
    curl \
        -H "Accept: application/json" \
        -H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
        -X GET \
    	"https://your.statseeker.server/api/v2.1/cdt_port/?fields=cdt_device.name,name,RxUtil,InOctets&timefilter=range=now%20-%201h%20to%20now&RxUtil_formats=avg,max&InOctets_formats=percentile&InOctets_stats=%7B%22percentile%22:90%7D&InOctets_sort=1,desc,percentile&limit=10&indent=3&links=none"
    
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.get(url, headers=headers, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/cdt_port'
    # specify fields to be returned
    query += '?fields=cdt_device.name,name,RxUtil,InOctets'
    # specify data formats
    query += '&RxUtil_formats=avg,max&InOctets_formats=percentile&InOctets_stats={"percentile":90}'
    # Filters and sorting
    query += '&timefilter=range=now -1h to now&InOctets_sort=1,desc,percentile&limit=10'
    # optional response formatting
    query += '&indent=3&links=none'
    # Run the request
    resp = do_request(server, query, user, pword)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword)
    	headers = {
    		:content_type => "json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :get,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false
    	)
    end
    
    def do_request(server, query, user, pword)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword)
        else
            # Authentication successful
            headers = {
    			:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
                :method => :get,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/cdt_port'
    # specify fields to be returned
    $query += '/?fields=cdt_device.name,name,RxUtil,InOctets'
    # specify data formats
    $query += '&RxUtil_formats=avg,max&InOctets_formats=percentile&InOctets_stats={"percentile":90}'
    # Filters and sorting
    $query += '&timefilter=range=now -1h to now&InOctets_sort=1,desc,percentile&limit=10'
    # optional response formatting
    $query += '&indent=3&links=none'
    # Run the request
    resp = do_request($server, $query, $user, $pword)
    puts "#{resp.to_str}"
    
    
    {
       "version":"2.1",
       "revision":"11",
       "info":"The Statseeker RESTful API",
       "data":{
          "success":true,
          "errmsg":"ok",
          "time":1623720470,
          "objects":[
             {
                "type":"cdt_port",
                "sequence":11,
                "status":{
                   "success":true,
                   "errcode":0
                },
                "data_total":21178,
                "data":[
                   {
                      "cdt_device.name":"R-GMM-AGG-07",
                      "name":"Po15",
                      "RxUtil":{
                         "max":15.4582,
                         "avg":13.5477
                      },
                      "InOctets":{
                         "percentile":112727000000.0
                      },
                      "id":28487
                   },
                   {
                      "cdt_device.name":"R-GMM-AGG-07",
                      "name":"Tu2924",
                      "RxUtil":{
                         "max":7.72051,
                         "avg":6.92405
                      },
                      "InOctets":{
                         "percentile":57139800000.0
                      },
                      "id":28512
                   },
                   {
                      "cdt_device.name":"R-GMM-AGG-07",
                      "name":"Tu3937",
                      "RxUtil":{
                         "max":7.71764,
                         "avg":6.82324
                      },
                      "InOctets":{
                         "percentile":54429300000.0
                      },
                      "id":28563
                   },
                   {
                      "cdt_device.name":"R-GMM-AGG-07",
                      "name":"Tu2942",
                      "RxUtil":{
                         "max":7.61665,
                         "avg":5.65903
                      },
                      "InOctets":{
                         "percentile":53692000000.0
                      },
                      "id":28528
                   },
                   {
                      "cdt_device.name":"R-GMM-AGG-07",
                      "name":"Tu2912",
                      "RxUtil":{
                         "max":4.5065,
                         "avg":3.86295
                      },
                      "InOctets":{
                         "percentile":32249500000.0
                      },
                      "id":28504
                   },
                   {
                      "cdt_device.name":"CDT-IP-Interface-Stats",
                      "name":"Ethernet3/30",
                      "RxUtil":{
                         "max":38.799,
                         "avg":35.7174
                      },
                      "InOctets":{
                         "percentile":28524500000.0
                      },
                      "id":25042
                   },
                   {
                      "cdt_device.name":"CDT-IP-Interface-Stats",
                      "name":"Ethernet3/27",
                      "RxUtil":{
                         "max":38.9375,
                         "avg":34.1723
                      },
                      "InOctets":{
                         "percentile":28171200000.0
                      },
                      "id":25038
                   },
                   {
                      "cdt_device.name":"R-GMM-AGG-07",
                      "name":"Tu3936",
                      "RxUtil":{
                         "max":3.8409,
                         "avg":3.41211
                      },
                      "InOctets":{
                         "percentile":27906200000.0
                      },
                      "id":28562
                   },
                   {
                      "cdt_device.name":"CDT-IP-Interface-Stats",
                      "name":"Ethernet3/18",
                      "RxUtil":{
                         "max":38.4306,
                         "avg":35.0934
                      },
                      "InOctets":{
                         "percentile":27854000000.0
                      },
                      "id":25028
                   },
                   {
                      "cdt_device.name":"CDT-IP-Interface-Stats",
                      "name":"Ethernet3/11",
                      "RxUtil":{
                         "max":35.2323,
                         "avg":28.6036
                      },
                      "InOctets":{
                         "percentile":25326800000.0
                      },
                      "id":25021
                   }
                ]
             }
          ]
       }
    }
    
    [top]

    Example: Return the Inbound Traffic 90th Percentile for the Last Hour on a specific Interface

    cURLPythonRubyResponse
    
    curl \
        -H "Accept: application/json" \
        -H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
        -X GET \
        "https://your.statseeker.server/api/v2.1/cdt_port/<INTERFACE ID>/RxUtil?timefilter=range=%20now%20-%201h%20to%20now&formats=percentile&stats=%7B%22percentile%22:90%7D&links=none&indent=3"
    	
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.get(url, headers=headers, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
        return resp
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/cdt_port/<INTERFACE ID>/RxUtil'
    # specify data formats
    query += '/?formats=percentile&stats={"percentile":90}'
    # Filters
    query += '&timefilter=range=now -1h to now'
    # optional response formatting
    query += '&indent=3&links=none'
    # Run the request
    resp = do_request(server, query, user, pword)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword)
    	headers = {
    		:content_type => "json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :get,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false
    	)
    end
    
    def do_request(server, query, user, pword)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword)
        else
            # Authentication successful
            headers = {
    			:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
                :method => :get,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/cdt_port/<INTERFACE ID>/RxUtil'
    # specify data formats
    $query += '/?formats=percentile&stats={"percentile":90}'
    # Filters
    $query += '&timefilter=range=now -1h to now'
    # optional response formatting
    $query += '&indent=3&links=none'
    # Run the request
    resp = do_request($server, $query, $user, $pword)
    puts "#{resp.to_str}"
    
    
    {
    
        'version':'2.1',
        'revision':'11',
        'info':'The Statseeker RESTful API',
        'data':{
            'success':True,
            'errmsg':'ok',
            'time':1623730579,
            'objects':[
                {
                    'type':'cdt_port',
                    'sequence':11,
                    'status':{
                        'success':True,
                        'errcode':0
                    },
                    'data_total':1,
                    'data':[
                        {
                            'RxUtil':{
                                'percentile':96.375
                            },
                            'id':<INTERFACE ID>
                        }
                    ]
                }
            ]
        }
    
    }
    
    [top]

    Example: Return traffic rate metrics for an interface, during business hours on a specific date

    We are:

    • Filtering to a specified interface on a specified device
    • Restricting the response to between 6am - 6pm, on March 5th 2020
    cURLPythonRubyResponse
    
    curl \
        -H "Accept: application/json" \
        -H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
        -X GET \
    	'https://your.statseeker.server/api/v2.1/cdt_port?fields=name,deviceid,cdt_device.name,ifAlias,ifDescr,RxBps&name_filter=IS("<INTERFACE NAME>")&cdt_device.name_filter=IS("<DEVICE NAME>")&formats=95th,median,avg&timefilter=range=2020-03-05 to 2020-03-06;time=08:00 to 18:00&indent=3&links=none'	
    	
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.get(url, headers=headers, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/cdt_port'
    # specify fields to be returned
    query += '/?fields=name,deviceid,cdt_device.name,ifAlias,ifDescr,RxBps'
    # specify data formats
    query += '&formats=95th,median,avg'
    # Filters
    query += '&name_filter=IS("<INTERFACE NAME>")&cdt_device.name_filter=IS("<DEVICE NAME>")&timefilter=range=2020-03-05 to 2020-03-06;time=08:00 to 18:00'
    # optional response formatting
    query += '&indent=3&links=none'
    # Run the request
    resp = do_request(server, query, user, pword)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword)
    	headers = {
    		:content_type => "json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :get,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false
    	)
    end
    
    def do_request(server, query, user, pword)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword)
        else
            # Authentication successful
            headers = {
    			:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
                :method => :get,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/cdt_port'
    # specify fields to be returned
    $query += '/?fields=name,deviceid,cdt_device.name,ifAlias,ifDescr,RxBps'
    # specify data formats
    $query += '&formats=95th,median,avg'
    # Filters
    $query += '&name_filter=IS("<INTERFACE NAME>")&cdt_device.name_filter=IS("<DEVICE NAME>")&timefilter=range=2020-03-05 to 2020-03-06;time=08:00 to 18:00'
    # optional response formatting
    $query += '&indent=3&links=none'
    # Run the request
    resp = do_request($server, $query, $user, $pword)
    puts "#{resp.to_str}"
    
    
    {
        "version": "2.1",
        "revision": "13",
        "info": "The Statseeker RESTful API",
        "data": {
            "success": true,
            "errmsg": "ok",
            "time": 1615501619,
            "objects": [
                {
                    "type": "cdt_port",
                    "sequence": 1,
                    "status": {
                        "success": true,
                        "errcode": 0
                    },
                    "data_total": 1,
                    "data": [
                        {
                            "name": "<INTERFACE NAME>",
                            "deviceid": 26478,
                            "cdt_device.name": "<DEVICE NAME>",
                            "ifAlias": "Link to SanJose-core",
                            "ifDescr": "GigabitEthernet0/1",
                            "RxBps": {
                                "avg": 19653900.0,
                                "median": 19410600.0,
                                "95th": 23579900.0
                            }
    						"id": 26486,
                        }
                    ]
                }
            ]
        }
    }
    
    [top]

    Group

    The group resource allows you to create and populate the groups used by Statseeker for reporting, and for authorization when restricting visibility and access to functionality for users within Statseeker.

    The group object
    Field ID Field Title Type Get, Add, Update Description
    entities Entities object G, U The entities that are assigned to this group

    Formats Description
    count Number of entities assigned to the group
    exc_count Number of entities assigned to the group (excluding child entities not explicitly assigned)
    exc_hexstr Hex bitstring representation of assigned entities (excluding child entities not explicitly assigned)
    exc_list Array of entity ids assigned to the group (excluding child entities not explicitly assigned)
    hexstr Hex bitstring representation of assigned entities
    list Array of entity ids assigned to the group
    objects Array of object names that have entities assigned to the group
    id ID integer G ID of the group
    name Name string G, A (required), U Name of the group


    Group Mode

    The Group object requires a mode be specified when performing PUT requests to make changes to the group's members (entities). The mode specifies what the API should do with the entities when making changes.

    Mode Description
    clear Remove the specified entities from the group
    set Remove all existing entities and then add the specified entities to the group
    add Add the specified entities to the group

    [top]

    Example: Create a Group

    cURLPythonRubyResponse
    
    curl \
    	-H "Accept: application/json" \
    	-H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    	-X POST \
    	"https://your.statseeker.server/api/v2.1/group/?indent=3" \
    	-d '{"data":[{"name":"<GROUP NAME>"}]}'
    
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword, reqData):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.post(url, headers=headers, data=reqData, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.post(url, headers=headers, auth=(user, pword), data=reqData, verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/group'
    # optional response formatting
    query += '/?indent=3&links=none'
    # data
    reqData = json.dumps({"data":[{"name":"<GROUP NAME>"}]})
    # Run the request
    resp = do_request(server, query, user, pword, reqData)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword, reqData)
    	headers = {
    		:content_type => "application/json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :post,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false,
    		:payload => reqData
    	)
    end
    
    def do_request(server, query, user, pword, reqData)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword, reqData)
        else		
            # Authentication successful
    		headers = {
    		:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
    			:method => :post,
    			:url => url,
    			:headers => headers,
    			:verify_ssl => false,
    			:payload => reqData
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword, reqData)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/group'
    # optional response formatting
    $query += '/?indent=3&links=none'
    # configure payload
    $reqData = '{"data":[{"name":"<GROUP NAME>"}]}'
    # Run the request
    resp = do_request($server, $query, $user, $pword, $reqData)
    puts "#{resp.to_str}"
    
    
    {
       "version":"2.1",
       "revision":"11",
       "info":"The Statseeker RESTful API",
       "data":{
          "success":true,
          "errmsg":"ok",
          "time":1623731624,
          "objects":[
             {
                "type":"group",
                "sequence":8,
                "status":{
                   "success":true,
                   "errcode":0
                },
                "data_total":1,
                "data":[
                   {
                      "name":"<GROUP NAME>",
                      "id":94551
                   }
                ]
             }
          ]
       }
    }
    
    [top]

    Example: Populate a Group

    When populating a group you use the /entities field endpoint and must specify a mode instructing the API on how to populate the group.

    cURLPythonRubyResponse
    
    curl \
    	-H "Accept: application/json" \
    	-H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    	-X PUT \
    	"https://your.statseeker.server/api/v2.1/group/<GROUP ID>/entities/?indent=3" \
    	-d '{"value":[286,287,288,289,290,291,292,293],"mode":"add"}'
    
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword, reqData):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.put(url, headers=headers, data=reqData, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.put(url, headers=headers, auth=(user, pword), data=reqData, verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/group/<GROUP ID>/entities'
    # optional response formatting
    query += '/?indent=3&links=none'
    # data
    reqData = json.dumps({"value":[286,287,288,289,290,291,292,293],"mode":"add"})
    # Run the request
    resp = do_request(server, query, user, pword, reqData)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword, reqData)
    	headers = {
    		:content_type => "application/json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :put,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false,
    		:payload => reqData
    	)
    end
    
    def do_request(server, query, user, pword, reqData)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword, reqData)
        else		
            # Authentication successful
    		headers = {
    		:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
    			:method => :put,
    			:url => url,
    			:headers => headers,
    			:verify_ssl => false,
    			:payload => reqData
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword, reqData)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/group/<GROUP ID>/entities'
    # optional response formatting
    $query += '/?indent=3&links=none'
    # configure payload
    $reqData = '{"value":[286,287,288,289,290,291,292,293],"mode":"add"}'
    # Run the request
    resp = do_request($server, $query, $user, $pword, $reqData)
    puts "#{resp.to_str}"
    
    
    {
       "info":"The Statseeker RESTful API",
       "data":{
          "errmsg":"ok",
          "success":true,
          "time":1496200162
       },
       "links":[
          {
             "link":"/api/v2.1/group/<GROUP ID>/entities?&indent=3",
             "rel":"self"
          },
          {
             "link":"/api/v2.1",
             "rel":"base"
          },
          {
             "link":"/api/v2.1/group/<GROUP ID>",
             "rel":"collection"
          }
       ],
       "api_version":"2.1"
    }
    
    [top]

    Example: Deleting a Group

    cURLPythonRubyResponse
    
    curl \
    	-H "Accept: application/json" \
    	-H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    	-X DELETE \
    	"https://your.statseeker.server/api/v2.1/group/<GROUP ID>/?indent=3&links=none" 
    
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.delete(url, headers=headers, data=reqData, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.delete(url, headers=headers, auth=(user, pword), data=reqData, verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/group/<GROUP ID>'
    # optional response formatting
    query += '/?indent=3&links=none'
    # Run the request
    resp = do_request(server, query, user, pword)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword)
    	headers = {
    		:content_type => "application/json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :delete,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false
    	)
    end
    
    def do_request(server, query, user, pword)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword, reqData)
        else		
            # Authentication successful
    		headers = {
    		:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
    			:method => :delete,
    			:url => url,
    			:headers => headers,
    			:verify_ssl => false
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/group/<GROUP ID>'
    # optional response formatting
    $query += '/?indent=3&links=none'
    # Run the request
    resp = do_request($server, $query, $user, $pword)
    puts "#{resp.to_str}"
    
    
    {
      "info": "The Statseeker RESTful API",
      "data": {
        "errmsg": "ok",
        "success": true,
        "time": 1496200297
      },
      "api_version": "2.1"
    }
    
    [top]

    Example: Which Groups contain a specific entity (device, interface, user, etc.)

    Return details on all groups containing a specified device.

    Note: the id is returned in the response of any request which returns the device. Simply send a GET to the /api/v2.1/cdt_device resource-level endpoint (filtering by the device name) to retrieve the id.
    cURLPythonRubyResponse
    
    curl \
    	-H "Accept: application/json" \
    	-H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    	-X GET \
    	"https://your.statseeker.server/api/v2.1/group/?fields=id,name,entities&entities_formats=count&entities_filter==<DEVICE ID>&entities_filter_format=list
    
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.get(url, headers=headers, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/group'
    # specify fields to be returned
    query += '/?fields=id,name,entities'
    # specify data formats
    query += '&entities_formats=count'
    # Filters
    query += '&entities_filter==<DEVICE ID>&entities_filter_format=list'
    # optional response formatting
    query += '&indent=3&links=none'
    # Run the request
    resp = do_request(server, query, user, pword)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}') 
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword)
    	headers = {
    		:content_type => "json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :get,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false
    	)
    end
    
    def do_request(server, query, user, pword)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword)
        else
            # Authentication successful
            headers = {
    			:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
                :method => :get,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/group'
    # specify fields to be returned
    $query += '/?fields=id,name,entities'
    # specify data formats
    $query += '&entities_formats=count'
    # Filters
    $query += '&entities_filter==<DEVICE ID>&entities_filter_format=list'
    # optional response formatting
    $query += '&indent=3&links=none'
    # Run the request
    resp = do_request($server, $query, $user, $pword)
    puts "#{resp.to_str}"
    
    
    {
        "version": "2.1",
        "revision": "13",
        "info": "The Statseeker RESTful API",
        "data": {
            "success": true,
            "errmsg": "ok",
            "time": 1615841935,
            "objects": [
                {
                    "type": "group",
                    "sequence": 9,
                    "status": {
                        "success": true,
                        "errcode": 0
                    },
                    "data_total": 5,
                    "data": [
                        {
                            "id": 156472,
                            "name": "10.100.*.*",
                            "entities": {
                                "count": 51173
                            }
                        },
                        {
                            "id": 156893,
                            "name": "US Hardware",
                            "entities": {
                                "count": 12044
                            }
                        },
                        {
                            "id": 233023,
                            "name": "Switches",
                            "entities": {
                                "count": 58583
                            }
                        },
                        {
                            "id": 233024,
                            "name": "Chicago",
                            "entities": {
                                "count": 2347
                            }
                        },
                        {
                            "id": 233025,
                            "name": "Chicago Switches",
                            "entities": {
                                "count": 1985
                            }
                        }
                    ]
                }
            ]
        }
    }
    
    [top]

    Using 'group_by' for Data Aggregation

    The group_by parameter can be used to aggregate data returned from a query, for more information on the syntax and requirements of using group_by, see the parameters available when using GET request to a resource-level endpoint.

    Example: Total traffic across all interfaces on a device

    Request the total bytes for all interfaces on every device in the Routers group for the previous 4hrs, then aggregate these values by the parent device, returning the total traffic for the device.

    cURLPythonRubyResponse
    
    curl \
    	-H "Accept: application/json" \
    	-H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    	-X GET \
    	"https://your.statseeker.server/api/v2.1/cdt_port/?fields=cdt_device.name,InOutOctets&formats=total&groups=Routers&timefilter=range%20=%20now%20-4h%20to%20now&group_by={cdt_device.name}&InOutOctets_aggregation_format=total&limit=0&links=none&indent=3" 
    
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.get(url, headers=headers, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/cdt_port'
    # specify fields to be returned
    query += '/?fields=cdt_device.name,InOutOctets'
    # specify filters
    query += '&groups=Routers&timefilter=range%20=%20now%20-4h%20to%20now&limit=0'
    # specify data formats
    query += '&formats=total&InOutOctets_aggregation_format=total'
    # group_by
    query += '&group_by={cdt_device.name}'
    # optional response formatting
    query += '&links=none&indent=3'
    # Run the request
    resp = do_request(server, query, user, pword)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}') 
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword)
    	headers = {
    		:content_type => "json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :get,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false
    	)
    end
    
    def do_request(server, query, user, pword)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword)
        else
            # Authentication successful
            headers = {
    			:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
                :method => :get,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/cdt_port'
    # specify fields to be returned
    $query += '/?fields=cdt_device.name,InOutOctets'
    # specify filters
    $query += '&groups=Routers&timefilter=range%20=%20now%20-4h%20to%20now&limit=0'
    # specify data formats
    $query += '&formats=total&InOutOctets_aggregation_format=total'
    # group_by
    $query += '&group_by={cdt_device.name}'
    # optional response formatting
    $query += '&links=none&indent=3'
    # Run the request
    resp = do_request($server, $query, $user, $pword)
    puts "#{resp.to_str}"
    
    
    {
        "version": "2.1",
        "revision": "12",
        "info": "The Statseeker RESTful API",
        "data": {
            "success": true,
            "errmsg": "ok",
            "time": 1669678227,
            "objects": [
                {
                    "type": "cdt_port",
                    "sequence": 0,
                    "status": {
                        "success": true,
                        "errcode": 0
                    },
                    "data_total": 56,
                    "data": [
                        {
                            "cdt_device.name": "Adelaide-rtr",
                            "InOutOctets": {
                                "total": 1175110000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Athens-rtr",
                            "InOutOctets": {
                                "total": 1645590000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Atlanta-Router1",
                            "InOutOctets": {
                                "total": 97008800000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Auckland-rtr",
                            "InOutOctets": {
                                "total": 1539760000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Baltimore-Router1",
                            "InOutOctets": {
                                "total": 59582500000.0
                            }
                        },
                        {
                            "cdt_device.name": "Bangalore-rtr",
                            "InOutOctets": {
                                "total": 198421000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Bangkok-rtr",
                            "InOutOctets": {
                                "total": 560997000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Barcelona-rtr",
                            "InOutOctets": {
                                "total": 1704780000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Beijing-rtr",
                            "InOutOctets": {
                                "total": 129280000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Brisbane-rtr",
                            "InOutOctets": {
                                "total": 2276180000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Budapest-rtr",
                            "InOutOctets": {
                                "total": 2740350000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Cairo-rtr",
                            "InOutOctets": {
                                "total": 2842820000000.0
                            }
                        },
                        {
                            "cdt_device.name": "CapeTown-rtr",
                            "InOutOctets": {
                                "total": 1930000000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Chennai-rtr",
                            "InOutOctets": {
                                "total": 121450000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Chicago-rtr",
                            "InOutOctets": {
                                "total": 2563840000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Copenhagen-rtr",
                            "InOutOctets": {
                                "total": 1343370000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Dallas-Router1",
                            "InOutOctets": {
                                "total": 17923100000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Dallas-Router11",
                            "InOutOctets": {
                                "total": 14284700000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Delhi-rtr",
                            "InOutOctets": {
                                "total": 3560040000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Denver-Router1",
                            "InOutOctets": {
                                "total": 45548100000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Denver-Router3",
                            "InOutOctets": {
                                "total": 1077640000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Development-router2",
                            "InOutOctets": {
                                "total": 8002710000.0
                            }
                        },
                        {
                            "cdt_device.name": "Dublin-rtr",
                            "InOutOctets": {
                                "total": 2349700000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Helsinki-rtr",
                            "InOutOctets": {
                                "total": 1523310000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Houston-rtr",
                            "InOutOctets": {
                                "total": 2465680000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Jakarta-rtr",
                            "InOutOctets": {
                                "total": 1730530000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Kolkata-rtr",
                            "InOutOctets": {
                                "total": 377560000000.0
                            }
                        },
                        {
                            "cdt_device.name": "KualaLumpur-rtr",
                            "InOutOctets": {
                                "total": 1229840000000.0
                            }
                        },
                        {
                            "cdt_device.name": "LasVegas-Router1",
                            "InOutOctets": {
                                "total": 514681000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Lisbon-rtr",
                            "InOutOctets": {
                                "total": 3719270000000.0
                            }
                        },
                        {
                            "cdt_device.name": "London-rtr",
                            "InOutOctets": {
                                "total": 1638650000000.0
                            }
                        },
                        {
                            "cdt_device.name": "LosAngeles-Router1",
                            "InOutOctets": {
                                "total": 831289000000.0
                            }
                        },
                        {
                            "cdt_device.name": "LosAngeles-rtr",
                            "InOutOctets": {
                                "total": 2485100000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Manila-rtr",
                            "InOutOctets": {
                                "total": 1811560000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Melbourne-rtr",
                            "InOutOctets": {
                                "total": 1788680000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Memphis-Router1",
                            "InOutOctets": {
                                "total": 67885500000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Milwaukee-Router1",
                            "InOutOctets": {
                                "total": 12570700000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Mumbai-rtr",
                            "InOutOctets": {
                                "total": 150878000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Nashville-Router1",
                            "InOutOctets": {
                                "total": 1759260000000.0
                            }
                        },
                        {
                            "cdt_device.name": "NewYork-Router1",
                            "InOutOctets": {
                                "total": 3185650000000.0
                            }
                        },
                        {
                            "cdt_device.name": "NewYork-Router2",
                            "InOutOctets": {
                                "total": 36924300000000.0
                            }
                        },
                        {
                            "cdt_device.name": "NewYork-rtr",
                            "InOutOctets": {
                                "total": 1760470000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Perth-rtr",
                            "InOutOctets": {
                                "total": 188290000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Phoenix-rtr",
                            "InOutOctets": {
                                "total": 1984780000000.0
                            }
                        },
                        {
                            "cdt_device.name": "PortElizabeth-rtr",
                            "InOutOctets": {
                                "total": 1614360000000.0
                            }
                        },
                        {
                            "cdt_device.name": "SanDiego-Router1",
                            "InOutOctets": {
                                "total": 21530400000000.0
                            }
                        },
                        {
                            "cdt_device.name": "SanFrancisco-Router1",
                            "InOutOctets": {
                                "total": 7373830000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Seattle-Router1",
                            "InOutOctets": {
                                "total": 1362710000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Shanghai-rtr",
                            "InOutOctets": {
                                "total": 824177000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Singapore-rtr",
                            "InOutOctets": {
                                "total": 171115000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Taipei-rtr",
                            "InOutOctets": {
                                "total": 2047740000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Tokyo-rtr",
                            "InOutOctets": {
                                "total": 1655830000000.0
                            }
                        },
                        {
                            "cdt_device.name": "UPS-voip-routers",
                            "InOutOctets": {
                                "total": 189781000.0
                            }
                        },
                        {
                            "cdt_device.name": "Warsaw-rtr",
                            "InOutOctets": {
                                "total": 3137920000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Wellington-rtr",
                            "InOutOctets": {
                                "total": 1554150000000.0
                            }
                        },
                        {
                            "cdt_device.name": "Zurich-rtr",
                            "InOutOctets": {
                                "total": 2984610000000.0
                            }
                        }
                    ]
                }
            ]
        }
    }
    
    [top]

    Example: Count of devices in each group
    cURLPythonRubyResponse
    
    curl \
    	-H "Accept: application/json" \
    	-H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    	-X GET \
    	"https://your.statseeker.server/api/v2.1/cdt_device?fields=count,~group~&count_field=id&count_aggregation_format=count&group_by={~group~}&limit=0&indent=3&links=none" 
    
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.get(url, headers=headers, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/cdt_device'
    # specify fields to be returned
    query += '/?fields=count,~group~&count_field=id'
    # specify data formats
    query += '&count_aggregation_format=count'
    # specify filters
    query += '&limit=0'
    # group_by
    query += '&group_by={~group~}'
    # optional response formatting
    query += '&indent=3&links=none'
    # Run the request
    resp = do_request(server, query, user, pword)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}') 
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword)
    	headers = {
    		:content_type => "json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :get,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false
    	)
    end
    
    def do_request(server, query, user, pword)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword)
        else
            # Authentication successful
            headers = {
    			:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
                :method => :get,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/cdt_device'
    # specify fields to be returned
    $query += '/?fields=count,~group~&count_field=id'
    # specify data formats
    $query += '&count_aggregation_format=count'
    # specify filters
    $query += '&limit=0'
    # group_by
    $query += '&group_by={~group~}'
    # optional response formatting
    $query += '&indent=3&links=none'
    # Run the request
    resp = do_request($server, $query, $user, $pword)
    puts "#{resp.to_str}"
    
    
    {
        'version':'2.1',
        'revision':'14',
        'info':'The Statseeker RESTful API',
        'data':{
            'success':True,
            'errmsg':'ok',
            'time':1669615015,
            'objects':[
                {
                    'type':'cdt_device',
                    'sequence':1,
                    'status':{
                        'success':True,
                        'errcode':0
                    },
                    'data_total':7,
                    'data':[
                        {
                            'count':22,
                            '~group~':'London'
                        },
                        {
                            'count':9,
                            '~group~':'Barcelona'
                        },
                        {
                            'count':66,
                            '~group~':'Routers'
                        },
                        {
                            'count':84,
                            '~group~':'Servers'
                        },
                        {
                            'count':332,
                            '~group~':'Switches'
                        },
                        {
                            'count':2,
                            '~group~':'one'
                        },
                        {
                            'count':86,
                            '~group~':None
                        }
                    ]
                }
            ]
        }
    }
    
    [top]

    Example: Average current ping of all devices in each group

    Request the current ping for all devices in the specified groups, then aggregate those values returning the average ping and device count for each group.

    cURLPythonRubyResponse
    
    curl \
    	-H "Accept: application/json" \
    	-H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    	-X GET \
    	"https://your.statseeker.server/api/v2.1/cdt_device?fields=~group~,ping_rtt,deviceCount&deviceCount_field=id&ping_rtt_formats=current&ping_rtt_aggregation_format=avg&deviceCount_aggregation_format=count&groups=Barcelona,Paris,London,Berlin,Dublin,Hamburg&group_by={~group~}&~group~_sort=1,asc&limit=0&links=none&indent=3" 
    
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.get(url, headers=headers, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/cdt_device'
    # specify fields to be returned
    query += '/?fields=~group~,ping_rtt,deviceCount&deviceCount_field=id'
    # specify data formats
    query += '&ping_rtt_formats=current&ping_rtt_aggregation_format=avg&deviceCount_aggregation_format=count'
    # specify filters
    query += '&groups=Barcelona,Paris,London,Berlin,Dublin,Hamburg&limit=0'
    # group_by
    query += '&group_by={~group~}'
    # optional response formatting
    query += '&~group~_sort=1,asc&indent=3&links=none'
    
    # Run the request
    resp = do_request(server, query, user, pword)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}') 
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword)
    	headers = {
    		:content_type => "json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :get,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false
    	)
    end
    
    def do_request(server, query, user, pword)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword)
        else
            # Authentication successful
            headers = {
    			:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
                :method => :get,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/cdt_device'
    # specify fields to be returned
    $query += '/?fields=~group~,ping_rtt,deviceCount&deviceCount_field=id'
    # specify data formats
    $query += '&ping_rtt_formats=current&ping_rtt_aggregation_format=avg&deviceCount_aggregation_format=count'
    # specify filters
    $query += '&groups=Barcelona,Paris,London,Berlin,Dublin,Hamburg&limit=0'
    # group_by
    $query += '&group_by={~group~}'
    # optional response formatting
    $query += '&~group~_sort=1,asc&indent=3&links=none'
    # Run the request
    resp = do_request($server, $query, $user, $pword)
    puts "#{resp.to_str}"
    
    
    {
        "version": "2.1",
        "revision": "12",
        "info": "The Statseeker RESTful API",
        "data": {
            "success": true,
            "errmsg": "ok",
            "time": 1669685626,
            "objects": [
                {
                    "type": "cdt_device",
                    "sequence": 1,
                    "status": {
                        "success": true,
                        "errcode": 0
                    },
                    "data_total": 6,
                    "data": [
                        {
                            "~group~": "Barcelona",
                            "ping_rtt": {
                                "current": 40.8889
                            },
                            "deviceCount": 18
                        },
                        {
                            "~group~": "Berlin",
                            "ping_rtt": {
                                "current": 43
                            },
                            "deviceCount": 6
                        },
                        {
                            "~group~": "Dublin",
                            "ping_rtt": {
                                "current": 42.5556
                            },
                            "deviceCount": 18
                        },
                        {
                            "~group~": "Hamburg",
                            "ping_rtt": {
                                "current": 30.5
                            },
                            "deviceCount": 4
                        },
                        {
                            "~group~": "London",
                            "ping_rtt": {
                                "current": 50.0476
                            },
                            "deviceCount": 44
                        },
                        {
                            "~group~": "Paris",
                            "ping_rtt": {
                                "current": 51.55
                            },
                            "deviceCount": 42
                        }
                    ]
                }
            ]
        }
    }
    
    [top]

    Syslog

    The syslog resource provides access to the syslog messages collected by Statseeker. The contents of these records can be reported on and used to trigger alerts.

    The syslog Object
    Field ID Field Title Type Get, Add, Update Description
    deviceid Device ID integer G The ID of the parent device of the entity that owns this message
    entityid Entity ID integer G The ID of the entity that owns this message
    id ID integer G Message Identifier
    text Message Text string G The message text
    time Time integer G, A Message Time
    type Type string G, A Message Type
    device Device string The name of the parent device of the entity that owns this message G, A
    entity Entity string G The name of the entity that owns this message
    Options
    • lastx - Display the last x records, rather than using a timefilter
    Links

    This resource has links to the following:

    [top]

    Example: Retrieving details, from Syslog Records, on devices that 'went down' in the previous 24hrs

    In this example we will retrieve details on all Syslog messages that contain a specified string, in the previous 24h hours.

    cURLPythonRubyResponse
    
    curl \
    	-H "Accept: application/json" \
    	-H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    	-X GET \
    	-u user:pword "https://your.statseeker.server/api/v2.1/syslog/?indent=3&links=none&fields=entity,entityid,text,type,time&text_filter=LIKE(%22<FILTER STRING>%22)&time_timefilter=range%20=%20now%20-%201d%20to%20now"
    
    
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.get(url, headers=headers, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/syslog'
    # specify fields to be returned
    query += '/?fields=entity,entityid,text,type,time'
    # Filters
    query += '&text_filter=LIKE("<FILTER STRING>")&time_timefilter=range = now - 1d to now'
    # optional response formatting
    query += '&indent=3&links=none'
    # Run the request
    resp = do_request(server, query, user, pword)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword)
    	headers = {
    		:content_type => "json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :get,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false
    	)
    end
    
    def do_request(server, query, user, pword)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword)
        else
            # Authentication successful
            headers = {
    			:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
                :method => :get,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/syslog'
    # specify fields to be returned
    $query += '/?fields=entity,entityid,text,type,time'
    # Filters
    $query += '&text_filter=LIKE("<FILTER STRING>")&time_timefilter=range = now - 1d to now'
    # optional response formatting
    $query += '&indent=3&links=none'
    # Run the request
    resp = do_request($server, $query, $user, $pword)
    puts '#{resp.to_str}'
    
    
    {
    	"info": "The Statseeker RESTful API",
    	"data": {
    		"objects": [{
    			"status": {
    				"errcode": 0,
    				"success": true
    			},
    			"data": [{
    				"text": "local0.info  %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/10, changed state to down",
    				"entity": "LosAngeles-swt1",
    				"time": 1490240152,
    				"entityid": 174,
    				"type": "syslog",
    				"id": 126619
    			}, {
    				"text": "local0.info  %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/7, changed state to down",
    				"entity": "Helsinki-swt1",
    				"time": 1490245557,
    				"entityid": 313,
    				"type": "syslog",
    				"id": 126626
    			}, {
    				"text": "local0.info  %LINEPROTO-5-UPDOWN: Line protocol on Interface GigabitEthernet1/0/12, changed state to down",
    				"entity": "CapeTown-swt2",
    				"time": 1490246759,
    				"entityid": 412,
    				"type": "syslog",
    				"id": 126628
    			}, {
    				"text": "local0.info  %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/18, changed state to down",
    				"entity": "Mumbai-swt2",
    				"time": 1490251556,
    				"entityid": 379,
    				"type": "syslog",
    				"id": 126631
    			}, {
    				"text": "local0.info  %LINK-3-UPDOWN: Interface FastEthernet0/19, changed state to down",
    				"entity": "Unknown (10.100.52.25)",
    				"time": 1490270147,
    				"entityid": 0,
    				"type": "syslog",
    				"id": 126641
    			}, {
    				"text": "local0.info  %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/24, changed state to down",
    				"entity": "Budapest-swt4",
    				"time": 1490271059,
    				"entityid": 271,
    				"type": "syslog",
    				"id": 126642
    			}, {
    				"text": "local0.info  %LINK-3-UPDOWN: Interface FastEthernet0/18, changed state to down",
    				"entity": "Phoenix-swt4",
    				"time": 1490271643,
    				"entityid": 201,
    				"type": "syslog",
    				"id": 126643
    			}, {
    				"text": "local0.info  %LINK-3-UPDOWN: Interface FastEthernet0/7, changed state to down",
    				"entity": "Bangkok-swt1",
    				"time": 1490279033,
    				"entityid": 374,
    				"type": "syslog",
    				"id": 126647
    			}, {
    				"text": "local0.info  %LINK-3-UPDOWN: Interface GigabitEthernet1/0/20, changed state to down",
    				"entity": "Unknown (10.100.52.25)",
    				"time": 1490286824,
    				"entityid": 0,
    				"type": "syslog",
    				"id": 126652
    			}, {
    				"text": "local0.info  %LINK-3-UPDOWN: Interface GigabitEthernet2/0/16, changed state to down",
    				"entity": "Chicago-rtr",
    				"time": 1490294444,
    				"entityid": 185,
    				"type": "syslog",
    				"id": 126657
    			}, {
    				"text": "local0.info  %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/8, changed state to down",
    				"entity": "Tokyo-swt1",
    				"time": 1490301348,
    				"entityid": 355,
    				"type": "syslog",
    				"id": 126661
    			}, {
    				"text": "local0.info  %LINK-3-UPDOWN: Interface GigabitEthernet1/0/8, changed state to down",
    				"entity": "LosAngeles-rtr",
    				"time": 1490305548,
    				"entityid": 175,
    				"type": "syslog",
    				"id": 126664
    			}, {
    				"text": "local0.info  %LINK-3-UPDOWN: Interface GigabitEthernet1/0/18, changed state to down",
    				"entity": "Helsinki-swt3",
    				"time": 1490307644,
    				"entityid": 311,
    				"type": "syslog",
    				"id": 126667
    			}, {
    				"text": "local0.info  %LINK-3-UPDOWN: Interface GigabitEthernet1/0/14, changed state to down",
    				"entity": "Athens-rtr",
    				"time": 1490316041,
    				"entityid": 299,
    				"type": "syslog",
    				"id": 126671
    			}, {
    				"text": "local0.info  %LINK-3-UPDOWN: Interface FastEthernet0/28, changed state to down",
    				"entity": "Melbourne-swt2",
    				"time": 1490316942,
    				"entityid": 397,
    				"type": "syslog",
    				"id": 126672
    			}, {
    				"text": "local0.info  %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/11, changed state to down",
    				"entity": "Chicago-swt2",
    				"time": 1490317855,
    				"entityid": 183,
    				"type": "syslog",
    				"id": 126673
    			}, {
    				"text": "local0.info  %LINK-3-UPDOWN: Interface GigabitEthernet3/0/5, changed state to down",
    				"entity": "Copenhagen-swt3",
    				"time": 1490318756,
    				"entityid": 331,
    				"type": "syslog",
    				"id": 126674
    			}],
    			"type": "syslog",
    			"data_total": 17
    		}],
    		"errmsg": "ok",
    		"success": true,
    		"time": 1490325593
    	},
    	"api_version": "2.1"
    }
    
    [top]

    Device and Interface Event Records (event_record)

    The event_record resource provides access to the device and interface events recorded by Statseeker. The contents of these records can be reported on and used to trigger alerts.

    The event_record Object
    Field ID Field Title Type Get, Add, Update Description
    delta Delta integer G The number of seconds since the last record of the same event
    device Device string G The name of the device that owns the entity
    deviceid Device ID integer G The ID of the device that owns the entity
    entity Entity string G The name of the entity that owns the event
    entityid Entity ID integer G, A The ID of the entity that owns the entity
    entityTypeName Entity Type Name string G The name of the type of entity that owns the event
    entityTypeTitle Entity Type Title string G The title of the type of entity that owns the event
    event Event string G, A The event text associated to the record
    eventid Event ID integer G, A (required) The event id associated to the record
    id ID string G Event Record Identifier
    note Note string G, U The note associated with the record
    state State string G, A (required) The state text associated to the record
    stateid State ID integer G, A The state id associated to the record
    time Time integer G, A Epoch time that the record was created
    Options
    • lastx - Display the last x records, rather than using a timefilter
    Links

    This resource has links to the following:

    [top]

    Example: Retrieving details, from Event Records, of interfaces that recovered from a 'down' state in the previous 3hrs

    The delta value, found in each record in the response, details the duration that the interface was in a down state.

    Note: a similar process can be used with the threshold_record resource to retrieve data on events triggered by breaches of configured thresholds.


    cURLPythonRubyResponse
    
    curl \
    	-H "Accept: application/json" \
    	-H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    	-X GET \
    	-u user:pword "https://your.statseeker.server/api/v2.1/event_record/?indent=3&links=none&fields=event,eventid,device,deviceid,state,delta,time&state_filter=IS(%22up%22)&event_filter=IS(%22IF-MIB.ifOperStatus%22)&time_timefilter=range%20=%20now%20-%203h%20to%20now"
    
    
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.get(url, headers=headers, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/event_record'
    # specify fields to be returned
    query += '/?fields=event,eventid,device,deviceid,state,delta,time'
    # Filters
    query += '&state_filter=IS("up")&event_filter=IS("IF-MIB.ifOperStatus")&time_timefilter=range = now - 3h to now'
    # optional response formatting
    query += '&indent=3&links=none'
    # Run the request
    resp = do_request(server, query, user, pword)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword)
    	headers = {
    		:content_type => "json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :get,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false
    	)
    end
    
    def do_request(server, query, user, pword)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword)
        else
            # Authentication successful
            headers = {
    			:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
                :method => :get,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/event_record'
    # specify fields to be returned
    $query += '/?fields=event,eventid,device,deviceid,state,delta,time'
    # Filters
    $query += '&state_filter=IS("up")&event_filter=IS("IF-MIB.ifOperStatus")&time_timefilter=range = now - 3h to now'
    # optional response formatting
    $query += '&indent=3&links=none'
    # Run the request
    resp = do_request($server, $query, $user, $pword)
    puts "#{resp.to_str}"
    
    
    {
    	"info": "The Statseeker RESTful API",
    	"data": {
    		"objects": [{
    			"status": {
    				"errcode": 0,
    				"success": true
    			},
    			"data": [{
    				"eventid": 17,
    				"time": 1490328180,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 185,
    				"delta": 23520,
    				"device": "Chicago-rtr",
    				"id": "58D49A74-1-1"
    			}, {
    				"eventid": 81,
    				"time": 1490324821,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 284,
    				"delta": 3960,
    				"device": "Warsaw-rtr",
    				"id": "58D48D55-1-1"
    			}, {
    				"eventid": 81,
    				"time": 1490327161,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 284,
    				"delta": 480,
    				"device": "Warsaw-rtr",
    				"id": "58D49679-1-1"
    			}, {
    				"eventid": 97,
    				"time": 1490329921,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 293,
    				"delta": 3540,
    				"device": "Athens-srv1",
    				"id": "58D4A141-1-1"
    			}, {
    				"eventid": 97,
    				"time": 1490332501,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 293,
    				"delta": 1080,
    				"device": "Athens-srv1",
    				"id": "58D4AB55-1-1"
    			}, {
    				"eventid": 129,
    				"time": 1490326021,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 334,
    				"delta": 4260,
    				"device": "Copenhagen-rtr",
    				"id": "58D49205-1-1"
    			}, {
    				"eventid": 145,
    				"time": 1490324821,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 350,
    				"delta": 6900,
    				"device": "Shanghai-rtr",
    				"id": "58D48D55-2-1"
    			}, {
    				"eventid": 145,
    				"time": 1490328421,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 350,
    				"delta": 2040,
    				"device": "Shanghai-rtr",
    				"id": "58D49B65-1-1"
    			}, {
    				"eventid": 177,
    				"time": 1490329802,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 378,
    				"delta": 19741,
    				"device": "Delhi-rtr",
    				"id": "58D4A0CA-1-1"
    			}, {
    				"eventid": 209,
    				"time": 1490332022,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 390,
    				"delta": 840,
    				"device": "Chennai-rtr",
    				"id": "58D4A976-1-1"
    			}, {
    				"eventid": 209,
    				"time": 1490332142,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 390,
    				"delta": 60,
    				"device": "Chennai-rtr",
    				"id": "58D4A9EE-1-1"
    			}, {
    				"eventid": 209,
    				"time": 1490332502,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 390,
    				"delta": 120,
    				"device": "Chennai-rtr",
    				"id": "58D4AB56-1-1"
    			}, {
    				"eventid": 225,
    				"time": 1490325842,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 414,
    				"delta": 840,
    				"device": "CapeTown-rtr",
    				"id": "58D49152-1-1"
    			}, {
    				"eventid": 225,
    				"time": 1490328002,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 414,
    				"delta": 1080,
    				"device": "CapeTown-rtr",
    				"id": "58D499C2-1-1"
    			}, {
    				"eventid": 241,
    				"time": 1490323442,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 417,
    				"delta": 300,
    				"device": "PortElizabeth-rtr",
    				"id": "58D487F2-1-1"
    			}, {
    				"eventid": 241,
    				"time": 1490327942,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 417,
    				"delta": 3900,
    				"device": "PortElizabeth-rtr",
    				"id": "58D49986-1-1"
    			}, {
    				"eventid": 241,
    				"time": 1490329982,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 417,
    				"delta": 1440,
    				"device": "PortElizabeth-rtr",
    				"id": "58D4A17E-1-1"
    			}, {
    				"eventid": 257,
    				"time": 1490326322,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 423,
    				"delta": 6060,
    				"device": "Pretoria-rtr",
    				"id": "58D49332-1-1"
    			}, {
    				"eventid": 257,
    				"time": 1490330462,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 423,
    				"delta": 2280,
    				"device": "Pretoria-rtr",
    				"id": "58D4A35E-2-1"
    			}, {
    				"eventid": 257,
    				"time": 1490331122,
    				"event": "IF-MIB.ifOperStatus",
    				"state": "up",
    				"deviceid": 423,
    				"delta": 360,
    				"device": "Pretoria-rtr",
    				"id": "58D4A5F2-1-1"
    			}],
    			"type": "event_record",
    			"data_total": 20
    		}],
    		"errmsg": "ok",
    		"success": true,
    		"time": 1490333357
    	},
    	"api_version": "2.0"
    }
    
    [top]

    Example: Retrieving details, from Event Records, of device down events in the previous 3hrs


    cURLPythonRubyResponse
    
    curl \
    	-H "Accept: application/json" \
    	-H "Content-Type: application/json" \
    	-H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
    	-X GET \
    	-u user:pword "https://your.statseeker.server/api/v2.1/event_record/?fields=event,eventid,device,deviceid,state,time&state_filter=IS('down')&event_filter=IS('ping_state')&time_timefilter=range%20=%20now%20-%203h%20to%20now&timefmt=%25A%20%25H:%25M:%25S%20(%25y-%25m-%25d)&links=none&limit=0"
    
    
    
    # import requests for handling connection and encoding
    import requests
    import json
    def do_request(server, query, user, pword):
        # Run auth request
        headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
        url = f'https://{server}/ss-auth'
        authData = {'user': user, 'password': pword}
        resp = requests.post(url, headers=headers, data=authData, verify=False)
        headers['Content-Type'] = 'application/json'
        url = f'https://{server}/{query}'
        print(f'Get Auth Token: {resp.status_code}')
        if resp.status_code == 200:    
            # Authentication successful
            myToken = resp.json()
            headers['Authorization'] = f'Bearer {myToken["access_token"]}'
            resp = requests.get(url, headers=headers, verify=False)
        if resp.status_code == 401:
            print(f'Token auth failed: {resp.status_code}, trying basic auth')
            # Either Authentication was unsuccessful, or API set to use basic auth
            # Try basic auth
            resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
        return resp
    
    # Statseeker Server IP
    server = 'your.statseeker.server'
    # credentials
    user = 'api_user'
    pword = 'user_password'
    # API root endpoint
    query = 'api/v2.1'
    # specify target endpoint
    query += '/event_record'
    # specify fields to be returned
    query += '/?fields=event,eventid,device,deviceid,state,time'
    # Filters
    query += '&state_filter=IS("down")&event_filter=IS("ping_state")&timefmt=%A %H:%M:%S (%y-%m-%d)'
    # optional response formatting
    query += '&indent=3&links=none&limit=0'
    # Run the request
    resp = do_request(server, query, user, pword)
    if resp.status_code == 200:
        print(resp.status_code)
        print(resp.json())
    else:
        print(f'Error: {resp.status_code} {resp.reason}')
    
    
    # install with: $ gem install rest-client
    require "rest_client"
    require "json"
    require "base64"
    
    def try_basic(server, query, user, pword)
    	headers = {
    		:content_type => "json"
    	}
    	url = "https://" + server + "/" + query
    	headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
    	return RestClient::Request.execute(
    		:method => :get,
    		:url => url,
    		:headers => headers,
    		:verify_ssl => false
    	)
    end
    
    def do_request(server, query, user, pword)
        # Run auth request
        headers = {
            :content_type => "application/x-www-form-urlencoded"
        }
        url = "https://" + server + "/ss-auth"
        authData = {
           :user => user,
           :password => pword
        }
        begin
            resp = RestClient::Request.execute(
                :method => :post,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
                :payload => authData
            )
        rescue RestClient::Unauthorized
    		# bad credentials
            try_basic(server, query, user, pword)
        else
            # Authentication successful
            headers = {
    			:content_type => "application/json"
    		}	
            url = "https://" + server + "/" + query
            rdata = JSON.parse(resp)
            headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
            return RestClient::Request.execute(
                :method => :get,
                :url => url,
                :headers => headers,
                :verify_ssl => false,
            )
        end
    	rescue RestClient::Unauthorized
    		# Statseeker may be configured for basic auth
            try_basic(server, query, user, pword)
    end
    # Statseeker Server IP
    $server = 'your.statseeker.server'
    # api user credentials
    $user = 'api_user'
    $pword = 'user_password'
    # api root endpoint
    $query = 'api/v2.1'
    # specify target endpoint
    $query += '/event_record'
    # specify fields to be returned
    $query += '/?fields=event,eventid,device,deviceid,state,time'
    # Filters and Formats
    # Note: your Ruby env may require that you html encode the '%' symbols in the timefmt value (as we have done here to '%25')
    # I.e. timefmt=%A %H:%M:%S (%y-%m-%d)      becomes     timefmt=%25A %25H:%25M:%25S (%25y-%25m-%25d)
    $query += '&state_filter=IS("down")&event_filter=IS("ping_state")&time_timefilter=range = now - 3h to now&timefmt=%25A %25H:%25M:%25S (%25y-%25m-%25d)'
    # optional response formatting
    $query += '&indent=3&links=none'
    # Run the request
    resp = do_request($server, $query, $user, $pword)
    puts "#{resp.to_str}"
    
    
    {
        "version": "2.1",
        "revision": "14",
        "info": "The Statseeker RESTful API",
        "data": {
            "success": true,
            "errmsg": "ok",
            "time": 1691532291,
            "objects": [
                {
                    "type": "event_record",
                    "sequence": 0,
                    "status": {
                        "success": true,
                        "errcode": 0
                    },
                    "data_total": 6,
                    "data": [
                        {
                            "event": ".ping_state",
                            "eventid": 432,
                            "device": "LosAngeles-srv1",
                            "deviceid": 348,
                            "state": "down",
                            "time": "Wednesday 06:54:54 (23-08-09)",
                            "id": "64D2AB9E-1-0"
                        },
                        {
                            "event": ".ping_state",
                            "eventid": 544,
                            "device": "LosAngeles-swt2",
                            "deviceid": 354,
                            "state": "down",
                            "time": "Wednesday 06:54:47 (23-08-09)",
                            "id": "64D2AB97-1-0"
                        },
                        {
                            "event": ".ping_state",
                            "eventid": 720,
                            "device": "Chicago-ups2",
                            "deviceid": 358,
                            "state": "down",
                            "time": "Wednesday 07:31:37 (23-08-09)",
                            "id": "64D2B439-1-0"
                        },
                        {
                            "event": ".ping_state",
                            "eventid": 1296,
                            "device": "Phoenix-ups2",
                            "deviceid": 374,
                            "state": "down",
                            "time": "Wednesday 06:54:51 (23-08-09)",
                            "id": "64D2AB9B-2-0"
                        },
                        {
                            "event": ".ping_state",
                            "eventid": 1568,
                            "device": "London-ups2",
                            "deviceid": 383,
                            "state": "down",
                            "time": "Wednesday 06:54:38 (23-08-09)",
                            "id": "64D2AB8E-1-0"
                        },
                        {
                            "event": ".ping_state",
                            "eventid": 1616,
                            "device": "London-srv1",
                            "deviceid": 384,
                            "state": "down",
                            "time": "Wednesday 05:55:50 (23-08-09)",
                            "id": "64D29DC6-1-0"
                        }
                    ]
                }
            ]
        }
    }
    
    [top]