Introduction
This document describes how to get started with the SquareOne API interface.
It is not intended to be a full user manual, but rather a short guide to provide an overview of the interface and describe the overall concepts and structure.
Topic Links
Scope
This document describes concepts and terminology associated with the SquareOne Server RESTful API .
For more in-depth, technical information, view the full web-based living documentation through the browser UI, which provides the standard Swagger style documentation for users familiar with API interaction.
Terminology
While these terms will be explained more fully in their respective sections, this is a useful and brief introduction to some of the terms used in this document and in the API. The endpoints for the API are grouped into categories, depending on the general items on which they operate. The items are called by the same terms present in the endpoint URL.
Endpoint: Effectively a URL to be used when making a request. The endpoints for the SquareOne API follow the standard conventions of RESTful APIs.
Asset: An asset is the representation of an individual device in the API. An asset may be either a physical IoT device on which the SquareOne Agent resides, or a metadata description of an asset in the SquareOne Companion.
Inventory: The inventory group of endpoints allows requests concerning files and software packages, or artifacts.
Artifact: An artifact refers to a metadata description of a file or software package in the context of the SquareOne API system. It becomes linked to the actual file or software package once an Artifact Version is created.
Artifact Version: Each artifact may have one or more versions, which provide a link to the file or software package residing in the SquareOne Companion filestore. Only versions can be deployed to assets.
API Endpoints
The common API endpoints are grouped and named by the areas to which they refer. The core areas are:
- Assets Management of assets (devices)
- Inventory Management of artifacts (software packages)
- Groups Management of asset groups (groups of devices)
Details of these are covered in the following sections.
Typically, the endpoints have the form of
{ SquareOneServer_URL }/v1/api/{ endpoint }
where SquareOneServer_URL is replaced by the URL of the server and endpoint (which may include further slash-based routing) is replaced with the rest of endpoint designation. The endpoints belonging to each of the aforementioned areas can be viewed through the online documentation.
Note that throughout this document, items italicized between curly braces, {} , are intended to be replaced with the actual items denoted.
Operations
Endpoint operations have several request types, the most common of which are GET , POST , HEAD , PATCH , and DELETE .
- GET normally retrieves the requested information, filtering by path parameters, query parameters, or both.
- POST sends information to the server, typically in the form of a JSON request body provided along with the request.
- HEAD returns information in the header reply of the request, most often the count of items after filtering parameters have been applied.
- PATCH updates fields in a pre-existing data structure based on the key-value pairs in the request body.
- DELETE will remove items, based on filtering conditions in the request.
Parameters
API parameters have two major types, path-based and query-based. The web-based documentation denotes which parameters are of each type for all parameters.
Path Parameters
Path parameters are used within the path of the REST call and are usually required. For example, in the endpoint:
/v1/api/assets/{ assetId }
the entirety of {assetId} is replaced with the id of the asset for that REST operation, e.g.:
/v1/api/assets/E96A813D-C1BA-4721-B151-018D32593281
Path parameters are specific to the endpoint and are usually restricted to one item.
Query Parameters
Query parameters are more generic in nature, and are appended after the rest of the endpoint, following a question mark (?). In most cases, several parameters can be applied, separated by ampersand (&) symbols. The SquareOne API interface uses the form-expand style of array expansion. Query parameters for the SquareOne API interface come in two main styles: string and numeric. These parameters are used either to filter objects returned or specify the object to be modified.
StringFilter
When using query parameters that conform to a string datatype, they can be provided either by a direct match or by one of several modifiers. For example, if a GET request is sent to the asset's endpoint:
/v1/api/assets?name=asset1
a direct match request would return all assets where the name of the asset was exactly asset1.
Most string-based query parameters for the SquareOne API interface will also accept modifiers on this match. These modifiers are similar to SQL operations. For example, the GET operation
/v1/api/assets?name.like=asset
would return all assets with names similar to asset, such as asset1, asset2, ASSET and so on, and the query
/v1/api/assets/?architecture.like=arm
would return all assets having ARM architecture.
The modifiers for string-based operations are:
- like
- equals
- notLike
- notEqualTo
- before
- after
- all
Note that the all modifier is not currently supported. Additionally, for StringFilters the equals modifier is equivalent to providing no modifiers, i.e. the GET request
/v1/api/assets?name=asset1
is equivalent to the GET request
/v1/api/assets?name.equals=asset1
For all these modifiers except before and after it is possible to chain several parameters separated by ampersand symbols, in effect providing an array of values. For example, the GET operation
/v1/api/assets?os.equals=windows&os.equals=linux
would return all assets where ‘os’ is either Windows or Linux.
NumericFilter
Query parameters for SquareOne endpoints that are numeric must be provided with a modifier using the dot notation as in the second (i.e. .like ) example above. This includes dates: even though they are input as an ISO string, they behave as numeric fields. An example using numeric filtering is
/v1/api/assets?type.before=2
which would return all assets where the type (a numeric field) is less than 2.
The modifiers available for numeric parameters are:
- before
- after
- min
- max
- equals
- notEqualTo
- inRange (with base and offset)
- notInRange (with base and offset)
Sorting
Most GET requests can be sorted on any field that is available in the filtering parameters and is specified by the sortBy modifier. Multiple fields may be used for hierarchical sorting by providing multiple sortBy query parameters. In addition, the sort direction can be specified using the sortDirection modifier, for which ASC (ascending) or DESC (descending) are allowed values.
Paged Results
Two other parameters, size and page , are supported to allow results to be retrieved a page at a time for display. For example, this returns the second page of the list of assets, when viewed 10 per page (page 0 being the first page):
/v1/api/assets/?size=10&page=1
Request Body
For operations requiring a request body, in particular POST and PATCH operations, the body should be supplied in the request. This is typically in JSON format, as an object with key:value pairs. For example, if a new asset description is to be added, the request body for the POST operation might look like this:
{
“assetId”: “asset1”
“serialNumber”: “asset1”
}
The exact key:value pairs vary according to the endpoint and are described by the schemas in the online documentation.
Assets
Assets in the API interface are generally equivalent to the devices in the overview diagram above. Any device that has the SquareOne Agent installed can be considered an asset. Asset descriptions can also be created through the API without the need for a physical device running the SquareOne Agent.
Banned Assets
If an asset is compromised or is simply no longer in service, it can be added to a banned assets list, and will be unable to register or connect to the SquareOne Server. Banned assets can later have their bans revoked.
Banned Asset Schema
Banned assets are description only and include the key:value pairs shown below.
Key |
Value Data Type |
Description |
assetId |
string |
The assedId of the asset that is to be banned |
serialNumber |
String |
The serialNumber of the banned asset. Usually matches the assetId |
createdAt |
ISO string date |
The timestamp at which the asset was banned |
Asset Schema
The asset description consists of several key:value pairs as denoted in the table below. Most fields can be used for both filtering and sorts on GET and HEAD operations and can be provided in the request body for POST and PATCH operations.
Note that some fields may not be present in all cases if there is no value for the field. The fields assetId, type, name and approvalState are always present.
Key |
Value Data Type |
Description |
|
approvalState |
string |
Whether the device is approved to connect to SquareOne. Can be one of: Complete, Failed, Invalid, Pending, Revoked |
|
assetId |
string |
A unique id for an asset |
|
name |
string |
A descriptive name for the asset |
|
type |
integer |
The type of an asset. New asset types can be added via the API. |
|
serialNumber |
string |
Defaults to the same as the assetId |
|
architecture |
string |
The type of processing architecture of the asset, for example ARM or X86 |
|
os |
string |
The operating system of the asset, for example Linux |
|
lastActive |
string |
The ISO formatted string of when the asset was last connected to the SquareOne Server |
|
hearbeatEnabled |
boolean |
Whether or not a heartbeat signal is enabled for the asset |
|
heartbeatInterval |
integer |
The interval at which to send the heartbeat in minutes |
|
healthState |
string |
An indication of the health status of the device, can be one of: attention, healthy, offline, warning |
|
attributes |
object |
An open object of key:value pairs to add additional information to the asset |
|
tenantId |
string |
The ID of the tenant that the asset belongs to (see 13.2) |
|
The attributes field is an arbitrary object where additional information, such as certificates, location, or customer name might reside.
Asset Endpoints
The asset endpoints will generally function on the stored asset descriptions, even without there necessarily being a connected device associated with the asset description. In most cases, the description is created when the device is registered though the SquareOne Agent, but this may not always be the case as assets can be created without an associated device. For a full list of all available endpoints with associated fields refer the online documentation.
Asset Groups
Assets may be placed into arbitrary groups and may belong to more than one group. While not seen in the asset schema above, the group schema will contain the assets belonging to a given group and will be described in more detail in the groups section below. Both group and notGroup may be used as filtering parameters on operations that act on assets, such as the GET operation under StringFilter and the deploy endpoint. Note that group and notGroup may not be used in the same request, only one or the other, and each may be used only once per request.
Inventory
The inventory endpoints involve accessing and versions. An artifact can be a static file for content to be deployed to an asset (such as images) or a software package to be installed. Similarly to assets, artifacts accessed via the API interface consist of an artifact description (or metadata) and the file or software package itself. Each artifact description exists only as a description until associated with a version of the file or software package. In addition, there is a set of filestore API endpoints for managing individual files.
Artifact Schema
This schema describes the artifact descriptions, which exist as a set of key:value pairs. Most fields can be used for filtering and sorts on API operations that support these query parameters, such as GET , or HEAD . Note that not all fields will be present in all artifact descriptions, as some fields are optional.
Key |
Value Data Type |
Description |
id |
integer |
A numeric identifier of the artifact. Note that values below 10001 are reserved for internal use, and one will be autogenerated if not provided. |
name |
string |
The name of the artifact |
description |
string |
A description of the artifact |
installTimeout |
integer |
The time in seconds before timeout when attempting to deploy and artifact version |
installAttempts |
integer |
The number of times to attempt to deploy an artifact |
architecture |
string |
(optional) |
os |
string |
The operating system of the asset for which the artifact is intended |
installType |
string |
One of a limited set of values, Copy, Zip, TarGz, Dpkg, RunAsInstaller, that indicate how the artifact should be deployed |
destinationPath |
string |
The destination path on the asset indicating where the artifact should be deployed. This is required by (and is only valid for) Copy, Zip, and TarGz install types. |
filename |
string |
The name of the file as it will exist on the device, which need not match the file name in the SquareOne filestore. This is required by (and only valid for) the Copy install type. |
Inventory/Artifact Endpoints
The inventory/artifact endpoints will generally function on the stored artifact descriptions, even without a file or software package version (see section 10.3) associated with the artifact. For a full list of all available endpoints with associated fields, refer to the online documentation.
Artifact Versions
Each artifact description can be associated with a number of versions. These versions are accessed through the id of the artifact, and the actual deployment of a file or software package happens through the version, not just through the artifact description. We recommend writing a thorough artifact description, associating it to a version. A PUT endpoint
/v1/api/inventory/artifacts/{ artifactId }/versions/{ versionId }
exists for this purpose. An artifact is not deployed to an asset, rather an artifact version is deployed. In this manner, updated versions of the same file or package can be tracked without the need for a separate artifact description for each incremental update. The path parameters of artifactId and versionId are part of the route. The artifactId (corresponding to the id in the artifact schema above) must be from a pre-existing artifact description, while the versionId should be incremented, and must be supplied as a 16-character hexadecimal string, e.g. (0001000000000000 and then incremented as 0001000000000001). A request body must be included in this PUT request, with the schema below
Key |
Value Data Type |
Description |
artifactId |
integer |
The artifactId matching the id in the artifact description schema |
versionId |
16-character hexadecimal string, 0 prefixed (no 0x) |
The version id |
name |
string |
A name for the version |
fileId |
string |
This must match a fileId of a file in the filestore |
postInstallCommand |
string |
An arbitrary command to run on the asset after installation, if desired |
Only after an artifact description has a version can that version be deployed to assets.
Deploying Artifact Versions
Once an artifact description is associated with a file or software package through this versioning process, it can be deployed to assets. The endpoint for this process is
/v1/api/inventory/artifacts/{ artifactId }/versions/ {versionId} /deploy
The artifact version for deployment is specified in the usual manner through the path parameters. A request body must be included in this case to indicate to which assets the artifact version should be deployed, and the install mode of the deployment. The request body includes two upper-level parameters, installMode and filters. i nstallMode can take on two values, immediate , or reboot . If immediate is selected, then the artifact version is installed immediately, if reboot is chosen, then the artifact version is installed when the asset is next rebooted. The filter option is somewhat more complex. It may consist of nested values on which to filter, or it may be empty {} indicating that the artifact version should be deployed to all assets. The fields available to filter on are shown below.
Key |
Value Data Type |
Modifiers |
name |
string |
StringFilter |
assetId |
string |
StringFilter |
serialNumber |
string |
StringFilter |
type |
number |
NumericFilter |
approvalState |
string |
StringFilter |
os |
string |
StringFilter |
architecture |
string |
StringFilter |
lastActive |
ISO string date |
NumericFilter |
group |
string |
StringFilter |
notGroup |
|
|
The modifiers are described in the parameters section above. The key:value pairs with their modifiers can be nested in an AND/OR manner. For example, if the artifact version is to be installed immediately to Linux assets with names like exampleAsset (which would include exampleAsset1, exampleAsset2 etc.), the request body would be like
{
“installMode”: “immediate”,
“filters”:
{
“name”: {“like”: “exampleAsset”},
“os”: {“equals”: “Linux”}
}
}
If instead the artifact version is to be deployed to assets that are running Linux OR Windows, the request body would be like
{
“installMode”: “immediate”,
“filters”:
{
“name”: {“like”: “exampleAsset”},
“os”: {“equals”: [“Linux”, “Windows”]}
}
}
Note the inclusion of an array for the OR filtering condition. In this manner, artifact versions can be deployed to very specific sets of assets. Artifact versions can also be deployed to groups, as detailed in the groups section. In this case, group and notGroup may be used in the query parameters. Note that group and notGroup cannot be used in the same request.
Groups
Assets may also be added to groups. A single asset may belong to multiple groups or to none. Many operations can be performed on groups of assets, such as deploying artifact versions to all assets in a group. The usual workflow for groups is first to create a group and then add assets to it. A group can be created using the endpoint
/v1/api/groups
and providing a request body with the name of the group.
Group Schema
The group schema, following the same pattern as above, also consists of key:value pairs. In this case, only the name of the group is required to create the group. A description may be provided if desired, and the rest of the fields are automatically populated.
Key |
Value Data Type |
Description |
id |
number |
Unique identifier for this group |
name |
string |
The name of the group. A value for this field is required to create a new group. |
description |
string |
A text description of the group |
healthInfo |
Object |
A breakdown of the health state of the group |
healthState |
string |
The overall health state of the group, one of: attention, healthy, offline, warning |
createdAt |
ISO string timestamp |
The timestamp of when the group was created |
updatedAt |
ISO string timestamp |
The timestamp of when a field in the group schema was last updated |
Group Endpoints
The group endpoints in the SquareOne Companion API allow management of group descriptions and are used to add and remove assets from groups. These endpoints provide the usual GET and POST operations for retrieving group descriptions and creating groups in addition to a PATCH endpoint for adding assets to groups. This PATCH endpoint
/v1/api/groups/{ name }/assets
is the primary mechanism for adding assets to groups via the API. In this case, a request body is used to select the assets to add to the group. The request body is structured similarly to the example in 10.4. A request body such as
{
“name”: {“like”: “asset1”}
}
would add all assets with a value in the name field of the asset description similar to asset1, which would include asset12 and asset123, and so on. Any of the asset fields may be used for filtering, and multiple may be provided. If no request body is provided, all assets will be added to the group.
IPSO Device Telemetry
Internet Protocol for Smart Devices, or IPSO, defines an object model standard for IoT devices representing measurable things. These are often sensors or actuators, but the standard is flexible enough that nearly any measurable item can be translated into a common object format and can thus be transmitted using nearly any communication protocol without the need for cumbersome translation layers. In most cases. the IPSO objects will not be accessed directly but will instead be included in telemetry messages destined for database message cues. The SquareOne implementation of the standard uses five primary fields, all with integer values. In the table below, the IPSO key name is the same as is used throughout the API.
IPSO Key |
Description |
Example |
comb |
Composite Object ID. A descriptor for a grouped set of actuators and/or sensors. This is a numeric composite type, defined by the IPSO standard. IPSO defines a generic composite type of value 4000, and this is used for many otherwise undefined composite objects. |
4000 – a generic composite object. This may represent, for example, a machine such as an air conditioner containing ISPO Object Types for temperature, switches to control fans, heating/cooling etc. |
combN |
Composite Object Instance. This is the index of the composite object. This allows for multiple composite objects with the same Composite Object ID. It may be any integer value greater than or equal to 0. |
1 – this is the second instance of the composite object (i.e. our second air conditioning unit). |
type |
Type ID. This is a numeric identifier for the IPSO Object type. Typically, this maps to an individual sensor or actuator type (e.g. temperature sensor or digital output). Where possible IPSO standard sensor or actuator IDs are used. |
3347 – a push button. |
typeN |
Type Instance. This is the index of the Type object. Instance indexes start at 0 for each type within a composite object. |
2 – this is our third push button. |
attribute |
The type of data that the object is reporting, as defined by IPSO. |
5524 – a duration. |
Readings from assets are intended to pass though the SquareOne Agent, which formats the data according to the IPSO protocol, and then transmits to the SquareOne Companion. Some devices may only have OS-related information such as RAM usage, but other devices may be connected to sensors of various sorts.
IPSO Endpoints
The IPSO endpoints for retrieving readings (IPSO objects) are of two main types, one where the individual readings are collected and the other where composite instances are listed.
/v1/api/assets/{ assetId }/telemetry/latest/readings
will retrieve the most recent telemetry readings from the given asset, while
/ v1/api/assets/{assetid}/telemetry/historical/{comb}/{combN}/{type}/{typeN}/objects
will retrieve readings from a specific sensor.
The returned historical readings include an order field which contains the timestamp encoded as 10 bytes represented as a 20-digit hex string:
8-byte field (16 hex digits) containing Unix epoch timestamp (seconds since 00:00:00 UTC on 1 January 1970) |
2-byte (4 hex digits) sequence number. Used if an edge client sends multiple telemetry packets in a second |
Security: Tokens and Headers
The SquareOne Companion API uses Bearer security. Once an Authorization token is obtained, all calls to the API should include the token in the header of the call, as shown in this example, where < token > is replaced with the actual token.
-- header ‘Authorization: Bearer < token >’
Roles and permissions
The SquareOne Companion API requires the user’s current role to contain the relevant permission(s) to use each endpoint.
A user can see their assigned roles ( roleIds ), default role ( primaryRoleId ), and permissions by using the
/auth/me/user
and
/auth/me/permissions
endpoints, as described in the online documentation.
For users with multiple roles who wish to use an API endpoint as if they are a user with a different role to their primaryRoleId, they can use the x-role header in any API requests.
For example, a user with:
{
roleIds: [“user”, “admin”],
primaryRoleId: “user”
}
who wanted to carry out an admin task would use the header “ x-role ”: “ admin ”.
For users with only one role, or users who are content to use their primary role, no x-role header is needed as the user’s primaryRoleId is used by default.
Multi-tenancy
In SquareOne Companion almost all endpoints are tenant-specific, meaning each tenant has their own list of assets, artifacts, files, asset types etc.
Therefore, for the SquareOne Companion API to allow a user to use a tenant-specific endpoint, two conditions are required:
- The user must specify the desired tenant for all requests.
- This is done by providing an x-tenant header, whose value consists of the ID of the desired tenant. For example, to retrieve the list of assets on the tenant with ID ‘example-tenant’, a header of “x-tenant”: “example-tenant” would need to be provided in the GET
- The user must have access to the requested tenant.
If the user is an instance admin user and their current role is ‘instance_admin’, then they have access to all tenants, so this requirement is always met. For all other users, they are required to have a user created for them on the tenant specified in the x-tenant header with at least one role assigned to them.
Date/Time Format
The API interface uses Javascript formatted dates, which is a simplification of the ISO8601 Extended Format:
YYYY-MM-DDTHH:mm:ss.sssZ
The letter T is the date/time separator and Z is the time zone offset specified as Z (for UTC) or either + or - followed by a time expression HH:mm.
Some parts (e.g. the time) of that format can be omitted. However:
- Years must have at least four digits
- Months/Days/Hours/Minutes/Seconds must have exactly 2 digits
- Milliseconds must have exactly 3 digits
These are some examples of valid date (time) strings:
-
2022-02-20
-
2022-02-20T13:54
-
2022-02-20T13:54:00
-
2022-02-20T13:54:00.000Z
-
2022-02-20T13:54:00.000+01:00