Device Configuration APIs

Axis devices are provided with a large range of APIs to interact with. These APIs are designed with different approaches depending on their functionality and purpose. Starting with firmware 11.8 and onward, Axis devices are provided with a new type of APIs for device administration (control and configuration) called Device Configuration APIs (DCA). These APIs are designed with a model-driven API development framework to create standardized APIs with a common look and feel.

This documentation will give an overview of how to understand and use DCAs. As mentioned above, DCAs are based on a model-driven API framework and described with an API definition language to express their structure and behavior.

  • The API Definition section explains how the API definitions should be interpreted.

  • The REST API section explains how the API definitions are mapped to a JSON-based RESTful protocol.

  • The Discovery section explains how clients and users can check available APIs and get information about them from the devices.

Warning
The framework itself and APIs provided with this framework are still in the development phase and are subject to breaking changes. The APIs should not be used in production environments until the APIs are in released state.

API Definition

The main goal of DCAs are to create APIs with similar look and feel that are easy to understand and use. To achieve this, DCAs are designed with a model-driven approach where the API structure and behavior are defined with an API description language explained in this section.

The definitions of APIs supported by a device are provided by the discovery module described in the Discovery section.

The API definitions are provided in the JSON format. They contain some basic API information and the API structure. The APIs are organized with a hierarchical structure that uses entity, property, and action elements as shown in the example below.

Entity elements are containers for other elements used to structure a hierarchy. Entities can have properties, actions, and sub-entities.

  • Entities can either be singleton entities or entity collections.

  • Singleton entities represent a single entity instance, whereas entity collections represent a collection of repeating entities.

  • Properties are objects that refer to a piece of data.

  • Entities and properties have standard operations such as SET, GET, ADD, and REMOVE.

  • Action elements perform a task when triggered and can contain both input and output data.

  • An API always has a top root entity.

foo.v1 (Root Entity)
|---subEntity (Entity)
|   |--propery1 (Property)
|   |--propery2 (Property)
|   |--action1 (Action)
|---subEntityCollection (Entity Collection)
|   |--propery1 (Property)
|   |--propery2 (Property)
|   |--action1 (Action)
|---property1 (Property)
|---property2 (Property)
|---action1 (Action)

Top level structure

The APIs are defined in JSON format. The following JSON data shows the top level structure of an API definition.

{
  "id": <string>,
  "version": <string>,
  "name": <string>,
  "state": <string>,
  "short_description": <string>,
  "description": <string>,
  "root_entity": <object>,
  "data_types": <object>
}
JSON object/propertyDescription
id=<string>The API identifier.
version=<string>The full version of the API. Released APIs use x.y.z format, beta APIs use x.0.0-beta.y, and alpha APIs use x.0.0-alpha.y.
name=<string>The user-friendly API name.
state=<string>The API State. Can be alpha, beta, or released.
short_description=<string>A short API description.
root_entity=<object>This property is the object that describes the root entity, the top node of the API tree structure. The content of this object is described in the Entity Definition section below.
data_types=<object>Contains the API-specific data type definitions. Each data type is defined as a separate JSON property where the property name is the data type name. The type definition format is explained in the Data Type Definition section.

Entity Definition

Entities are used as containers for other property, entity, and action objects that create the API hierarchy. The following table describes the entity JSON object format:

"<entity name>": {
  "short_description": <string>,
  "collection": <string enum>,
  "key_property": <string>,
  "dynamic_support": <boolean>,
  "properties": {
    "property1": <property object>,
    "propertyN": <property object>
  },
  "entities": {
    "entity1": <entity object>,
    "entityN": <entity object>
  },
  "actions": {
    "action1": <entity object>,
    "actionN": <entity object>
  },
  "operations: {
    "get": {},
    "set": {
      "fields": {
        "optional": <array of fields>
      }
    },
    "add": {
      "roles": <array of roles>,
      "fields": {
        "required": <array of fields>,
        "optional": <array of fields>
      }
    },
    "remove": {
    "roles": <array of roles>
    }
  }
}
JSON object/propertyDescription
short_description=<string>A short entity description.
collection=<string enum>Specifies if the entity is a singleton or a collection entity. The value is set to "singleton" for singleton and "map" for collection entities.
key_property=<boolean>Specifies the key property that is only available for collection entities. The value contains the name of the property within the entity used to identify the items in the collection.
dynamic_support=<boolean>Specifies if the entity is dynamically supported.
If true, there will be another runtime meta property indicating if the entity is supported. The name of the meta property is {entity name}_supported.
If the meta property is false the entity value will be null.
propertiesContains properties belonging to the entity.
properties.<NAME>Each property of the entity is defined as a separate object. The structure of a property definition is explained below.
actionsContains actions belonging to the entity.
actions.<NAME>Each action of the entity is defined as a separate object. The structure of an action definition is explained below.
entitiesThis object contains sub-entities belonging to the entity.
entities.<NAME>Each sub-entity is defined as a separate object. The structure of an entity definition is explained in this table.
operationsSpecifies the operations that can be performed on the entity/entity collection.
operations.getSpecifies if the entity is gettable. If an entity has gettable properties/entities, the entity itself will become gettable.
operations.setSpecifies if the entity is settable.
operations.set.fields.optionalList of fields that can be used when setting the entity.
operations.addSpecifies if entities can be added to an entity collection. This operation is only available for collection entities.
operations.add.rolesList of roles that can perform the add operation.
operations.add.fields.optionalList of optional fields that can be used when adding an entity to a collection.
operations.add.fields.requiredList of required fields that must be provided when adding an entity to a collection.
operations.removeSpecifies if entities can be deleted from an entity collection. This operation is only available for collection entities.
operations.remove.rolesList of roles that can perform the remove operation.

Property Definition

Properties are objects representing a piece of information. This information can be read-only, write-only, or read-write depending on the operations defined on the property. The following table describes the property JSON object format:

"<property name>": {
  "short_description": <string>,
  "data_type": <string>,
  "nullable": <boolean>,
  "dynamic_support": <boolean>,
  "dynamic_range_constraints": <boolean>,
  "dynamic_value_constraints": <boolean>,
  "operations": {
    "get": {
      "roles": <array of roles>
    },
    "set": {
      "roles": <array of roles>
    }
  }
}
JSON object/propertyDescription
short_description=<string>A short property description.
data_type=<string>The data type of the property. It defines the data format used for the SET and GET operations. The type can be either a built-in or API-specific defined type. Built-in types are string, integer, number, and boolean. API-specific types are part of the API definition, and described in the Data Type Definition section.
nullable=<boolean>Specifies if the value can be null.
dynamic_support=<boolean>Specifies if the property has dynamic support. If true, there will be another meta property indicating if the property is supported. The name of the meta property is {property name}_supported. If the meta property is false, the property value will be null and can't be set.
dynamic_value_constraints=<boolean>Specifies if the property has dynamic value support. If true, there will be a meta property named {property name}_values with a list of valid values. The value of this meta property can be updated at runtime.
dynamic_range_constraints =<boolean>

Specifies is the property has dynamic range support. If true, there will be a meta property name {property name}_ranges with a list of range couples. The value of this meta property can be updated at runtime.

operations=<object>This object contains supported operations by the property.
operations.get=<object>Specifies if the GET operation is supported. The GET operation makes the property readable.
operations.get.roles=<object>A  list of roles that can perform the GET operation. The value can be a combination of adminoperator, and viewer.
operations.set=<object>Specifies if the SET operation is supported. The SET operation makes the property writable.
operations.set.roles=<string list>A list of roles that can perform the SET operation. The value can be a combination of adminoperator, and viewer.

Action Definition

Actions are objects that can be triggered to perform a specific task. The following table describes the action JSON object format:

"<action name>": {
  "short_description": <string>,
  "request_data_type": <string>,
  "response_data-type": <string>,
  "operations": {
    "trigger": {
      "roles": <array of role strings>
    }
  }
}
JSON object/propertyDescription
short_descriptionA short action description.
request_data_typeThe data type of the input value provided in the action request. It can be a built-in or API- specific data type.
response_data_typeThe data type of the output value returned in the action response. It can be a built-in or API-specific data type.
operationsContains operations supported by the action. Only trigger operation is supported.
operations.triggerSpecifies if the TRIGGER operation is supported. TRIGGER operation makes the action callable.
opoerations.trigger.rolesA list of roles that can trigger the action. The value can be a combination of adminoperator, and viewer.

Data Type Definition

String

String data types are defined with the following JSON format:

"<type name>": {
  "type": "string",
  "minLength": <minimum length>,
  "maxLength": <maximum length>,
  "format": "data-time|time|date",
  "pattern": "<regular expression>",
  "enum": ["<value1>", "<value2>", ...],
  "description": "<description of the type>"
}
JSON propertyDescription
typeThis property is set to ”string” for string types.
minLength
Optional
The minimum string length.
maxLength
Optional
The maximum string length.
format
Optional
The string format. Can be "date-time""time", or "date".
pattern
Optional
Regular expression (JavaScript (ECMA 262)) for string validation.
enum
Optional
Lists valid values.
descriptionA short data type description.

Integer

Integer data types are defined with the following JSON format:

"<type name>": {
  "type": "integer",
  "minimum": <minimum value>,
  "maximum": <maximum value>,
  "enum": [<int value1>, <int value2>, ...],
  "description": "<description of the type>"
}
JSON propertyDescription
typeThis property is set to "integer" for integer types.
minimum
Optional
The minimum integer value.
maximum
Optional
The maximum integer value.
enum
Optional
Lists of valid values.
descriptionA short data type description.

Number

Number data types are used to define floating numbers, and are defined with the following JSON format:

"<type name>": {
  "type": "number",
  "minimum": <minimum value>,
  "maximum": <maximum value>,
  "description": "<description of the type>"
}
JSON propertyDescription
typeThis property is set to "number" for floating number types.
minimum
Optional
The minimum value.
maximum
Optional
The maximum value.
descriptionA short data type description.

Boolean

Boolean data types are defined with the following JSON format:

"<type name>": {
  "type": "boolean",
  "description": "<description of the type>"
}
JSON propertyDescription
typeThis property is set to "boolean" for boolean types.
descriptionA short data type description.

Array

Array data types are defined with the following JSON format:

"<type name>": {
  "type": "array",
  "items": {
    "type": "<type name of array elements>",
    "nullable": <boolean>
  },
  "minItems": <integer>,
  "maxItems": <integer>,
  "description": "<description of the type>"
}
JSON propertyDescription
typeThis property is set to ”array” for array types.
items.typeThe data type of the items this array can contain.
items.nullableSpecifies if this array can contain null values.
minItems
Optional
The minimum number of items this array can contain.
maxItems
Optional
The maximum number of items this array can contain.
descriptionA short data type description.

Complex

Complex data types define data structures with fields, they are defined with the following JSON format:

"<type name>": {
  "type": "object",
  "properties": {
    "<field name 1>": {
      "type": "<type of the field>",
      "nullable": <boolean>,
      "description": "<description of the field>"
    },
    "<field name 2>": {...},
    "<field name 3>": {...},
    ...
  },
  "description": "<description of the type>"
}
JSON propertyDescription
typeThis property is set to ”object” for complex data types.
propertiesContains the fields of the complex type.
properties.<field name>Specifies a field of the complex type. Each field is defined with a separate sub-property.
properties.<field name>.typeThe field data type.
properties.<field name>.nullableSpecifies if the field can contain a null value.
properties.<field name>.descriptionA short description of the field.
descriptionA short data type description.

Object path

Each object (entity, property, and action) defined in an API can be identified with an object path. The path consists of object names separated with dots (.). The first two segments are always the API ID and version like foo.v1. They always point to the root entity of an API.

Items in an entity collection are identified by appending a key value encapsulated within [''] to the entity name like foo.v1.users['user1'].

Here is a list of possible path combinations based on the given API example:

foo.v1 (Root Entity)
|---users (Entity Collection)
|   |---comment (Property)
|   |---password (Property)
|   |---username (Property)
|---service (Entity)
    |---enabled (Property)
    |---restart (Action)

foo.v1
foo.v1.users (addressing the collection)
foo.v1.users['user1'] (addressing an item in the collection)
foo.v1.users['user1'].comment
foo.v1.users['user1'].password
foo.v1.users['user1'].username
foo.v1.service
foo.v1.service.enabled
foo.v1.service.restart

This notation is used when referring to an object defined in the API structures.

REST API

APIs are described with an API definition language that doesn't contain any information about the actual protocol and are exposed as REST APIs. Entities, properties, actions, and their operations are systematically mapped to URL endpoints and HTTP methods.

The device provides an OpenAPI specification and a rendered UI for each API. This specification contains the whole REST API mapping. The location of this specification and how to view it is described in the Discovery section.

All APIs can be accessed securely with TLS support (HTTPS) and should be the preferred choice.

URL Structure and Object Mapping

All APIs are located under /config/rest/ endpoint with their own root URL. The API ID and major version are used to specify the starting point mapped to /config/rest/{API_ID}/v{MAJOR_VER}[alpha|beta], where API_ID is the API ID and MAJOR_VER is the major version of the API. Released APIs have no suffixes, whereas alpha and beta state APIs have alpha and beta suffixes after the API major version.

Examples

https://my.device/config/rest/foo1/v1
https://my.device/config/rest/foo2/v1alpha
https://my.device/config/rest/foo3/v1beta
http://my.device/config/rest/foo4/v2

Root entity mapping

The root entity is a singleton entity and is mapped to the API starting point /config/rest/{API_ID}/v{MAJOR_VER}[alpha|beta].

http://my.device/config/rest/foo/v1
http://my.device/config/rest/foo2/v1alpha
http://my.device/config/rest/foo3/v1beta

Singleton entity mapping

Singleton entities are mapped to a subpath segment below its parent entity path.

foo.v1.parentEntity.childEntity
http://my.device/config/rest/foo/v1/parentEntity/childEntity

Collection entity mapping

Collection entities are mapped to a subpath segment below its parent entity path.

foo.v1.parentEntity.collectionEntity
http://my.device/config/rest/foo/v1/parentEntity/collectionEntity

Items inside collection entities are mapped with the key value of the instance below the entity collection path.

foo.v1.parentEntity.collectionEntity['item1']
http://my.device/config/rest/foo/v1/parentEntity/collectionEntity/item1

Property mapping

Properties are mapped to a subpath segment below its parent entity path.

foo.v1.parentEntity.childEntity.someProperty
http://my.device/config/rest/foo/v1/parentEntity/childEntity/someProperty

Action mapping

Actions are mapped to a subpath segment below its parent entity path.

foo.v1.parentEntity.doSomething
http://my.device/config/rest/foo/v1/parentEntity/doSomething

Object paths are converted to URLs by replacing the separator dot (.) and [' '] with /.

The following example lists all possible path combinations based on the given API structure:

foo.v1 (Root Entity)
|---users (Entity Collection)
|   |---comment (Property)
|   |---password (Property)
|   |---username (Property)
|---service (Entity)
    |---enabled (Property)
    |---restart (Action)
foo.v1 -> /config/rest/foo/v1
foo.v1.users -> /config/rest/foo/v1/users
foo.v1.users['user1'] -> /config/rest/foo/v1/users/user1
foo.v1.users['user1'].comment -> /config/rest/foo/v1/users/user1/comment
foo.v1.users['user1'].password -> /config/rest/foo/v1/users/user1/password
foo.v1.users['user1'].username -> /config/rest/foo/v1/users/user1/username
foo.v1.service -> /config/rest/foo/v1/service
foo.v1.service.enabled -> /config/rest/foo/v1/service/enabled
foo.v1.service.restart -> /config/rest/foo/v1/service/restart

Operation mapping

Operations are mapped to HTTP methods. Possible operations and their mappings are given below with request-response examples.

Examples given for the operations further below are using the following API structure:

foo.v1 (Root Entity)
|---users (Entity Collection)
|   |---comment (Property)
|   |---password (Property)
|   |---username (Property)
|---service (Entity)
    |---enabled (Property)
    |---portNumber (Property)
    |---restart (Action)

Get a property

The get operation for a property is mapped to HTTP GET on the property endpoint.

GET /config/rest/foo/v1/service/enabled HTTP/1.1
HOST: my-device
Content-Type: application/json

HTTP/1.1 200 OK
Content-Type: application/json
{
  "status": "success",
  "data": true
}

Set a property

The set operation for a property is mapped to HTTP PATCH method on the property endpoint.

Warning
Firmware versions 11.10 and prior use HTTP PUT instead of HTTP PATCH.
PATCH /config/rest/foo/v1/users/user1/password HTTP/1.1
HOST: my-device
 Content-Type: application/json
{
  "data": : "!my-new-password!"
}
 HTTP/1.1 200 OK
Content-Type: application/json
{
  "status": "success"
}

Get an entity

The get operation for a singleton entity is mapped to HTTP GET method on the entity endpoint.

GET /config/rest/foo/v1/service HTTP/1.1
HOST: my-device
Content-Type: application/json

HTTP/1.1 200 OK
Content-Type: application/json
{
  "status": "success",
  "data": {
    "enabled": true,
    "portNumber": 30001
  }
}

Set an entity

The set operation for a singleton entity is mapped to HTTP PATCH method on the entity endpoint.

Warning
Firmware versions 11.10 and prior use HTTP PUT instead of HTTP PATCH.
PATCH /config/rest/foo/v1/service HTTP/1.1
HOST: my-device
Content-Type: application/json
{
  "data": {
    "enabled": true,
    "portNumber": 30008
  }
}

HTTP/1.1 200 OK
Content-Type: application/json
{
  "status": "success"
}

Get all entity instances from an entity collection

The get operation for an entity collection is mapped to HTTP GET method on the entity collection endpoint.

GET /config/rest/foo/v1/users HTTP/1.1
HOST: my-device
 Content-Type: application/json

HTTP/1.1 200 OK
Content-Type: application/json
{
  "status": "success",
  "data": [
    {
      "username": "username1",
      "comment": "comment1"
    },
    {
      "username": "username2",
      "comment": "comment2"
    }
  ]
}

Get an entity instance from an entity collection

The get operation for an entity instance in a collection is mapped to HTTP GET method on the entity instance endpoint.

GET /config/rest/foo/v1/users/user1 HTTP/1.1
HOST: my-device
 Content-Type: application/json

HTTP/1.1 200 OK
Content-Type: application/json
{
  "status": "success",
  "data": {
    {
      "username": "username1",
      "comment": "comment1"
    }
}

Set an entity instance in an entity collection

The set operation for an entity instance in a collection is mapped to HTTP PATCH method on the entity instance endpoint.

Warning
Firmware versions 11.10 and prior use HTTP PUT instead of HTTP PATCH.
PATCH /config/rest/foo/v1/users/user1 HTTP/1.1
HOST: my-device
 Content-Type: application/json
{
  "data": {
    "username": "username1",
    "comment": "comment1"
  }
}

HTTP/1.1 200 OK
Content-Type: application/json
{
  "status": "success"
}

Add an entity instance to an entity collection

The add operation for an entity collection is mapped to HTTP POST method on the entity collection endpoint.

POST /config/rest/foo/v1/users HTTP/1.1
HOST: my-device
Content-Type: application/json
{
  "data": {
    "username": "username1",
    "password": "!new-user-password!",
    "comment": "some user comment"
  }
}

HTTP/1.1 200 OK
Content-Type: application/json
{
  "status": "success"
}

Delete an entity instance from an entity collection

The remove operation for an entity collection is mapped to HTTP DELETE method on the entity instance endpoint.

DELETE /config/rest/foo/v1/users/user1 HTTP/1.1
 HOST: my-device
 Content-Type: application/json

HTTP/1.1 200 OK
Content-Type: application/json
{
  "status": "success"
}

Trigger an action

The trigger operation for an action is mapped to HTTP POST method on the action endpoint.

Warning
Firmware versions 11.10 and prior use HTTP PUT instead of HTTP POST.
POST /config/rest/foo/v1/service/restart HTTP/1.1
HOST: my-device
Content-Type: application/json
{
  "data": {}
}

HTTP/1.1 200 OK
Content-Type: application/json
{
  "status": "success",
  "data": {}
}

Error handling

Client requests can fail for many reasons, such as validation, access rights, resource limitation, etc. If a request fails, a failure response with standard HTTP error status code and message will be returned. The payload will include a common error data structure in JSON format with a separate error code and a human-readable message.

The HTTP error response looks like this:

HTTP/1.1 <HTTP ERROR STATUS CODE> <HTTP ERROR STATUS MESSAGE>
Content-Type: application/json
{
  "status": "error",
  "error": {
    "code": <integer error code>,
    "message": "<user friendly error message>"
  }
}

Discovery

As part of the DCA framework, devices are provided with a discovery module that can be used to get the available APIs and detailed information about them.

/config/discover is the entry point to the discovery module which provides all available information.

The following example shows how to get the discovery root document:

GET /config/discover HTTP/1.1
HOST: my.device.com
Content-Type: application/json

HTTP/1.1 200 OK
Content-Type: application/json
{
  "framework_version":"1.0.0-beta.1",
  "apis":{...}
}

/config/discover/apis endpoint provides a list of available APIs and details about them.

The following example shows how to get all available APIs and the details about them:

GET /config/discover/apis HTTP/1.1
HOST: my.device.com
Content-Type: application/json

HTTP/1.1 200 OK
Content-Type: application/json
{
  "ssh": {
    "v1": {
      "doc": "/config/discover/apis/ssh/v1/doc.md",
      "doc_html": "/config/web-ui/cu-doc.html?md-doc-loc=/config/discover/apis/ssh/v1/doc.md",
      "model": "/config/discover/apis/ssh/v1/model.json",
      "rest_api": "/config/rest/ssh/v1beta",
      "rest_openapi": "/config/discover/apis/ssh/v1/openapi.json",
      "rest_ui": "/config/web-ui/swagger-ui/?url=/config/discover/apis/ssh/v1/openapi.json",
      "state": "beta",
      "version": "1.0.0-beta.1"
    },
    "v2": {...},
    ...
  },
  "cert": {
    "v1": {
      "doc": "/config/discover/apis/cert/v1/doc.md",
      "doc_html": "/config/web-ui/cu-doc.html?md-doc-loc=/config/discover/apis/cert/v1/doc.md",
      "model": "/config/discover/apis/cert/v1/model.json",
      "rest_api": "/config/rest/cert/v1beta",
      "rest_openapi": "/config/discover/apis/cert/v1/openapi.json",
      "rest_ui": "/config/web-ui/swagger-ui/?url=/config/discover/apis/cert/v1/openapi.json",
      "state": "beta",
      "version": "1.0.0-beta.0"
    },
    "v2": {...},
    ...
  },
  ...
}

Each API is identified by its ID and major version. In the previous example, ssh and cert APIs had single major versions. It is possible to have multiple major versions of an API at the same time.

/config/discover/apis/{API_ID} provides a list of all available major versions of the same API, where {API_ID} it the API ID.

The following example shows how to get all the available versions of a specific API:

GET /config/discover/apis/ssh HTTP/1.1
HOST: my.device.com
Content-Type: application/json

HTTP/1.1 200 OK
Content-Type: application/json
{
  "ssh": {
    "v1": {...},
    "v2": {...},
    ...
  }
}

/config/discover/apis/{API_ID}/v{MAJOR_VERSION} provides information of a specific API version, where {API_ID} it the API ID and {MAJOR_VERSION} is the major version of the API.

The following example shows how to get a specific version of an API:

GET /config/discover/apis/ssh/v1 HTTP/1.1
HOST: my.device.com
Content-Type: application/json

HTTP/1.1 200 OK
Content-Type: application/json
{
  "doc": "/config/discover/apis/ssh/v1/doc.md",
  "doc_html": "/config/web-ui/cu-doc.html?md-doc-loc=/config/discover/apis/ssh/v1/doc.md",
  "model": "/config/discover/apis/ssh/v1/model.json",
  "rest_api": "/config/rest/ssh/v1beta",
  "rest_openapi": "/config/discover/apis/ssh/v1/openapi.json",
  "rest_ui": "/config/web-ui/swagger-ui/?url=/config/discover/apis/ssh/v1/openapi.json",
  "state": "beta",
  "version": "1.0.0-beta.1"
}

The following table describes the API JSON object used in the previous examples:

JSON propertyDescription
modelA link to the API definition. The content format of this file is described in theAPI Definition section.
versionThe full API version. Follows the Semantic Versioning format, where released APIs use x.y.z format, beta APIs use x.0.0-beta.y, and alpha APIs use x.0.0-alpha.y.
stateThe API state . Can be alpha, beta or released.
docLink to the API documentation, presented in the Markdown format. This file contains simplified documentation of the API.
doc_htmlLocation for the rendered API documentation.
rest_apiAPI endpoint. This is the location of the root entity of the API.
rest_openapiThe OpenAPI specification for the API. This specification describes all the available endpoints, the methods, and the request/response payloads.
rest_uiLocation of the UI that renders the corresponding OpenAPI specification. This UI can be used as a supporting tool to interact with the API.