API Reference

The NITO API is RESTful. In short, this means that it uses HTTP response codes to indicate API errors or success.

The API is accessed by posting JSON data over HTTPS to a listening API service within your network. For instance, to post data locally to an agent API running on the local machine, the URL would typically start with https://localhost:6486/api/v1/. The API binds to 0.0.0.0 and port 6486, by default, so that you can access it anywhere within your network. Take care to never open the port that NITO is listening on to the world; the NITO agent requires only outbound access to communicate with the NITO central servers.

Enabling the API service is simply a matter of clicking New Device in the NITO dashboard and choosing NITO RESTful API. You will be prompted to indicate which agent will listen for API requests (peer agent). Once created, the peer agent will automatically install a separate NITOAPI service on the same machine that the agent is already running on, and you'll be provided an API key to be included in your API calls. Multiple RESTful API devices/keys can be generated for any agent under your account. An API device/key associated with an agent can be used only with that one agent.

Scripting examples

Examples are available for bash (Linux/MacOS/etc) and PowerShell (Windows), using the 'curl' and 'Invoke-RestMethod' commands, respectively.

Node.js examples are provided using the request library. Node.js is an intuitive option for working with JSON data, for all major platforms.

When you see example code, use the buttons above to toggle the language displayed.

Invoke-RestMethod...
curl...
request...

Authentication

Authenticate your calls by including the appropriate API key in the JSON post body of all requests. You can find your API key for a specific device by clicking API Key & Options in the Device Configuration window of a RESTful API device.

IMPORTANT: An API key will be authorized only by the single peer agent listening for the associated RESTful API device. An agent is not aware of the API keys for any other devices under your account and will not be able to accept data points or actions for others.

All API requests must be made over HTTPS. Calls made over plain HTTP will fail. The agent automatically generates a unique self-signed certificate when it installs the API service for the first time. The nito-api.crt and nito-api.key files in the NITO bin directory may be replaced by your own, CA-signed certificate+key. For the purpose of encrypting API calls, the auto-generated certificate should be sufficient in most cases, provided that your scripts are written to accept self-signed certificates (i.e., curl --insecure). If you have strict TLS/SSL certificate requirements, please replace the crt and key files as descriibed above (the NITO API binds to 0.0.0.0 by default; you can use the IP address of any network interface on the machine, and any hostname).

NOTE: When starting for the first time, the NITOAPI service may take a few minutes to generate a strong key file, and will not start accepting HTTPS requests until the nito-api.key file has been written to disk.

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
Invoke-RestMethod -Uri $API_URL -Method POST -ContentType "application/json" -Body $JSON
curl --insecure -v -H "Content-Type: application/json" -X POST -d "${JSON}" ${API_URL}
request.post(API_URL, {rejectUnauthorized: false, json: true, body: JSON }, (err, response, body) => { /* ... */ });

The JSON request body for all calls must be an <object> that contains at minimum the api_key member.

A minimal JSON string may start something like this:

{"api_key": "aBcDeFgHiJkLmNoPqRsTuVwXyZaBcDeFgHiJkLmNoPqRsTuVwX"...

Additionally, you can test all requests without actually performing the action, by including the <boolean> test member:

{"api_key": "aBcDeFgHiJkLmNoPqRsTuVwXyZaBcDeFgHiJkLmNoPqRsTuVwX", "test": true...

Errors

NITO uses conventional HTTP response codes to indicate the success or failure of an API request. In general: Codes in the 2xx range indicate success. Codes in the 4xx range indicate an error due to the information provided (e.g., method URL not found, invalid API key, bad JSON fields, etc.). Codes in the 5xx range indicate issues with the NITOAPI service.

The same HTTP code may be returned for a variety of different reasons, and so when a request fails, additional information will be included in the JSON response body as failure_message<string>.

HTTP status code summary

200 - OK The call was accepted by the local API service and is in queue to be delivered to NITO's central servers.
299 - OK (testing) The request was valid but will not be relayed to NITO's central servers because the 'test' flag was used.
400 - Bad Request Perhaps the most common error, usually due to a missing or invalid parameter in the request.
401 - Unauthorized The api_key provided is invalid or missing in the request. The listening agent will only accept API keys directly associated with it.
403 - Forbidden The call you are making is valid and authorized, however, the action you are requesting is forbidden (usually due to being overlimit for number of metrics).
404 - Not Found The REST method as specified by the URL of the request is invalid.
429 - Too Many Requests Too many API calls are being made to the agent too quickly and it cannot process this request. It's suggested to backoff the number of calls you are making. The NITO agent does not explicitly impose a rate-limit on the number of API calls you can make, however, the ability to process requests fast enough is dependant on the machine that the agent is running on.
500, 502, 503, 504 - Server Errors Something went wrong in the NITO agent or at NITO's central servers.

Add Data Point(s)

Adds data point(s) to the device view.

Method URL
/api/v1/datapoint/add
Arguments
  • api_key<string> required

    Must be included in every API request. You can find the api_key by clicking 'API Key & Options' in the 'Device Configuration' window for the API device.

  • metrics<array> required

    An array of metrics, where each element of the array is an object defining a unique metric (see 'metrics' child object arguments)

  • 'metrics' child object arguments
  • points<array> required

    An array of points, where each element of the array is a nested array with a length of 2

    • 0<number> required

      The timestamp of the data point in the number of seconds since midnight, January 1, 1970 GMT (UNIX Epoch time). This will define how the data point will be graphed along the x axis in the dashboard. Data points with a duplicate timestamp of a previously posted timestamp for the same metric will be discarded.

    • 1<number> required

      The value of the data point. This will define how the data point will be graphed along the y axis in the dashboard. Alerting thresholds may be defined for this value with the 'RESTful API Data Point' alarm.

  • name<string> required 1-1024 chars.

    The name of the metric. This will define how the data points will be organized in the default view for the device. All data points with different instance names (see 'instance' member) that share the same metric name will appear in the same graph, and can be filtered or aggregated within that graph by instance name.

    Must not contain Carriage Return (ASCII 13, \r) nor Line Feed (ASCII 10, \n) nor '#' characters. Uppercase A-Z will be converted to lowercase. Unicode is supported.

    IMPORTANT: There is a hard limit of 500 unique metric + instance combinations allowed for the lifetime of a single API device/key. If you exceed this, calls containing new metric + instance combinations will fail with code 403. For example, do not use highly dynamic fields, like process PID, as a metric or instance name.

  • instance<string> optional 1-1024 chars.

    An optional instance name. All data points sharing the same metric name will appear in the same graph and may be separated be the 'instance' member. Metric names/instances will be displayed in the NITO dashboard and alerts by concatenating the metric name with the instance name, delimited by a '#' character, e.g., 'disk used#c:\'.

    Must not contain Carriage Return (ASCII 13, \r) nor Line Feed (ASCII 10, \n). Uppercase A-Z will be converted to lowercase. Unicode is supported.

    IMPORTANT: There is a hard limit of 500 unique metric + instance combinations allowed for the lifetime of a single API device/key. If you exceed this, calls containing new metric + instance combinations will fail with code 403. For example, do not use highly dynamic fields, like process PID, as a metric or instance name.

  • severity<number|string> optional.

    May be defined to trigger the 'API/Extension Status' alarm using custom logic, as a <string> "ok"; "warning"; "critical"; "down", or a level of severity <number> 0; 1; 2; 3, respectively. We recommend using the 'RESTful API Data Point' alarm for simple alerting purposes, as that alarm offers finer configuration of thresholds directly in the NITO UI.

  • max <number> optional.

    An optional upper limit for fixing the y axis of graphs displayed in the dashboard for the related data points.

  • units<string> optional 1-10 chars.

    An optional 'units' string to be suffixed to the value as displayed on legends in the dashboard. e.g., '%'; 'Mbits/sec'; etc.

    IMPORTANT: There is a hard limit of 50 unique 'units' allowed for the lifetime of a single API device/key. If you exceed this, calls containing new 'units' will fail with code 403.

  • tags<array> optional.

    An array of arbitrary strings to assist with filtering data in the dashboard. The metric + instance combination is associated with only the latest tags posted with it, e.g., if you post tags ["a", "b"]; the unique metric + instance combination can then be filtered in the dashboard by "a" and/or "b", if you later post ["a", "c"], only "a" and/or "c" will match. As such, post associated tags with every datapoint.

    IMPORTANT: There is a hard limit of 500 unique tags allowed for the lifetime of a single API device/key (this count is independent of your 500 metric + instance limit, i.e., your unique metric + instance combinations can share unique tags). If you exceed this, calls containing new tags will fail with code 403. For example, do not use highly dynamic fields, like process PID, as a tag name.

$API_URL = "https://localhost:6486/api/v1/datapoint/add"

# Set API_KEY, VALUE, and SEVERITY variables here, using your own credentials and monitoring logic.

$TIMESTAMP = [Math]::Floor([decimal](Get-Date(Get-Date).ToUniversalTime()-uformat "%s"))

$MAKEJSON = {
@"
{
"api_key": "$API_KEY",
"metrics": [
    {
        "name": "disk used percentage",
        "instance": "c:\\",
        "points": [[$TIMESTAMP, $VALUE]],
        "severity": "$SEVERITY",
        "max": 100,
        "units": "%",
        "tags": ["os", "storage spaces"]
    }
]
}
"@
}

$JSON = &$MAKEJSON
$JSON = $JSON -replace "`n", "" -replace "`r", "" -replace "`t", ""

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
Invoke-RestMethod -Uri $API_URL -Method POST -ContentType "application/json" -Body $JSON
API_URL="https://localhost:6486/api/v1/datapoint/add"

# Set API_KEY, VALUE, and SEVERITY variables here, using your own credentials and monitoring logic.

TIMESTAMP=`date +%s`

JSON=`printf '{\
    "api_key": "%s",\
    "metrics": [\
        {\
            "name": "disk used percentage",\
            "instance": "/",\
            "points": [[%d, %d]],\
            "severity": "%s",\
            "max": 100,\
            "units": "%%",\
            "tags": ["os", "lvm"]\
        }\
    ]\
    }'\
    $API_KEY\
    $TIMESTAMP\
    $VALUE\
    $SEVERITY\
`

curl --insecure -v -H "Content-Type: application/json" -X POST -d "${JSON}" ${API_URL}
const request = require("request");

const API_URL = "https://localhost:6486/api/v1/datapoint/add";

/* Set API_KEY, VALUE, and SEVERITY variables here, using your own credentials and monitoring logic. */

const TIMESTAMP = Math.floor(Date.now() / 1000);

const JSON = {
    "api_key": API_KEY,
    "metrics": [
        {
            "name": "disk used percentage",
            "instance": "/",
            "points": [[TIMESTAMP, VALUE]],
            "severity": SEVERITY,
            "max": 100,
            "units": "%",
            "tags": ["os", "lvm"]
        }
    ]
};

request.post(API_URL, {rejectUnauthorized: false, json: true, body: JSON }, (err, response, body) => { /* ... */ });