REST API

NSoT is designed as an API-first application so that all possible actions are published as API endpoints.

API Reference

Interactive API reference documentation can be found by browsing to /docs/ on a running NSoT server instance.

Browsable API

Because NSoT is an API-first application, the REST API is central to the experience. The REST API can support JSON or can also be used directly from your web browser. This version is called the “browsable API” and while it doesn’t facilitate automation, it can be very useful.

Visit /api/ in your browser on your installed instance. How cool is that?!

Authentication

Two methods of authentication are currently supported.

User Authentication Header

This is referred to internally as auth_header authentication.

In normal operation NSoT is expected to be run behind an authenticating proxy that passes back a specific header. By default we expect X-NSoT-Email, though it is configurable using the USER_AUTH_HEADER setting.

The value of this header must be the user’s email and is formatted like so:

X-NSoT-Email: {email}

AuthToken

This is referred to internally as auth_token authentication.

API authentication requires the email and secret_key of a user. When a user is first created, a secret_key is automatically generated. The user may obtain their secret_key from the web interface.

Users make a POST request to /api/authenticate/ to passing email and secret_key in JSON payload. They are returned an auth_token that can then be used to make API calls. The auth_token is short-lived (default is 10 minutes and can be change using the AUTH_TOKEN_EXPIRY setting). Once the token expires a new one must be obtained.

The auth_token must be sent to the API using an Authorization header that is formatted like so:

Authorization: AuthToken {email}:{secret_key}

Requests

In addition to the authentication header above all POST, PUT, and PATCH, requests will be sent as JSON rather than form data and should include the header Content-Type: application/json

PUT requests are of note as they are expected to set the state of all mutable fields on a resource. This means if you don’t specificy all optional fields may revert to their default values, depending on the object type.

PATCH allows for partial update of objects for most fields, depending on the object type.

OPTIONS will provide the schema for any endpoint.

Responses

All responses will be in format along with the header Content-Type: application/json set.

The JSON payload will be in one of two potential structures and will always contain a status field to distinguish between them. If the status field has a value of "ok", then the request was successful and the response will be available in the data field.

{
    ...
}

If the status field has a value of "error" then the response failed in some way. You will have access to the error from the error field which will contain an error code and message.

{
    "error": {
        "code": 404,
        "message": "Resource not found."
    }
}

Schemas

By performing an OPTIONS query on any endpoint, you can obtain the schema of the resource for that endpoint. This includes supported content-types, HTTP actions, the fields allowed for each action, and their attributes.

An example response for the schema for the devices endpoint might look like:

Request:

OPTIONS http://localhost:8990/api/devices/

Response:

HTTP 200 OK
Allow: GET, POST, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "name": "Device List",
    "description": "API endpoint that allows Devices to be viewed or edited.",
    "renders": [
        "application/json",
        "text/html"
    ],
    "parses": [
        "application/json",
        "application/x-www-form-urlencoded",
        "multipart/form-data"
    ],
    "actions": {
        "PUT": {
            "id": {
                "type": "integer",
                "required": false,
                "read_only": true,
                "label": "ID"
            },
            "hostname": {
                "type": "string",
                "required": true,
                "read_only": false,
                "label": "Hostname",
                "max_length": 255
            },
            "attributes": {
                "type": "field",
                "required": true,
                "read_only": false,
                "label": "Attributes",
                "help_text": "Dictionary of attributes to set."
            }
        },
        "POST": {
            "hostname": {
                "type": "string",
                "required": true,
                "read_only": false,
                "label": "Hostname",
                "max_length": 255
            },
            "attributes": {
                "type": "field",
                "required": false,
                "read_only": false,
                "label": "Attributes",
                "help_text": "Dictionary of attributes to set."
            },
            "site_id": {
                "type": "integer",
                "required": true,
                "read_only": false,
                "label": "Site id"
            }
        }
    }
}

Performing Set Queries

Set Queries allow you to perform complex lookups of objects by attribute/value pairs and are available on all Resources at the /api/:resource/query/ list endpoint for a given resource type.

To perform a set query you must perform a GET request to the query endpoint providing the set query string as a value to the query argument.

For example:

Request:

GET /api/devices/query/?query=vendor=juniper

Response:

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "attributes": {
            "owner": "jathan",
            "vendor": "juniper",
            "hw_type": "router",
            "metro": "lax"
        },
        "hostname": "lax-r2",
        "site_id": 1,
        "id": 2
    },
    {
        "attributes": {
            "owner": "jathan",
            "vendor": "juniper",
            "hw_type": "router",
            "metro": "iad"
        },
        "hostname": "iad-r1",
        "site_id": 1,
        "id": 5
    }
]

The optional unique argument can also be provided in order to ensure only a single object is returned, otherwise an error is returned.

Request:

GET /api/devices/query/?query=metro=iad&unique=true

Response:

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "attributes": {
            "owner": "jathan",
            "vendor": "juniper",
            "hw_type": "router",
            "metro": "iad"
        },
        "hostname": "iad-r1",
        "site_id": 1,
        "id": 5
    }
]

If multiple results match the query, when unique has been specified, an error will be returned.

Request:

GET /api/devices/query/?query=vendor=juniper

Response:

HTTP 400 Bad Request
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "error": {
        "message": {
            "query": "Query returned 2 results, but exactly 1 expected"
        },
        "code": 400
    }
}