NAV Navigation
HTTP Shell Python Go Java JavaScript PHP Ruby

Introduction

Welcome to the Mender API reference documentation.

REST

The Mender API is a RESTful API. This means that the API is designed to allow you to get, create, update, & delete objects with the HTTP verbs GET, POST, PUT, PATCH, & DELETE. The APIs make use of CORS (cross-origin-request) which also uses the OPTIONS request method.

Device and Management APIs

The public APIs are split into two types - Device and Management. Device APIs are for device-originating requests, the Management APIs are intended for use by the UI and other tools that manage devices, Artifacts or deployments across devices.

API Versioning and compatibility

The APIs are being continuously reviewed and improved.

The following changes are considered backwards-compatible and users of the APIs should be flexible enough to handle them:

If API compatibility needs to be broken at some point, the version number in the URI will be increased, e.g. from /api/management/v1/deployments to /api/management/v2/deployments. In such cases, both versions will be supported by the server for some period to allow for graceful transition.

Device APIs

Device authentication

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

An API for device authentication handling. Intended for use by devices.

Base URLs:

Authenticate Device

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/devices/v1/authentication/auth_requests \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-MEN-Signature: string' \
  -H 'Authorization: API_KEY'

POST https://hosted.mender.io/api/devices/v1/authentication/auth_requests HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json
X-MEN-Signature: string

const inputBody = '{
  "id_data": "{\"mac\":\"00:01:02:03:04:05\"}",
  "pubkey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzogVU7RGDilbsoUt/DdH\nVJvcepl0A5+xzGQ50cq1VE/Dyyy8Zp0jzRXCnnu9nu395mAFSZGotZVr+sWEpO3c\nyC3VmXdBZmXmQdZqbdD/GuixJOYfqta2ytbIUPRXFN7/I7sgzxnXWBYXYmObYvdP\nokP0mQanY+WKxp7Q16pt1RoqoAd0kmV39g13rFl35muSHbSBoAW3GBF3gO+mF5Ty\n1ddp/XcgLOsmvNNjY+2HOD5F/RX0fs07mWnbD7x+xz7KEKjF+H7ZpkqCwmwCXaf0\niyYyh1852rti3Afw4mDxuVSD7sd9ggvYMc0QHIpQNkD4YWOhNiE1AB0zH57VbUYG\nUwIDAQAB\n-----END PUBLIC KEY-----\n"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'X-MEN-Signature':'string',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/devices/v1/authentication/auth_requests',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'X-MEN-Signature' => 'string',
  'Authorization' => 'API_KEY'
}

result = RestClient.post 'https://hosted.mender.io/api/devices/v1/authentication/auth_requests',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'X-MEN-Signature': 'string',
  'Authorization': 'API_KEY'
}

r = requests.post('https://hosted.mender.io/api/devices/v1/authentication/auth_requests', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'X-MEN-Signature' => 'string',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://hosted.mender.io/api/devices/v1/authentication/auth_requests', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/devices/v1/authentication/auth_requests");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "X-MEN-Signature": []string{"string"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/devices/v1/authentication/auth_requests", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /auth_requests

Submit an authentication request

The device presents its unique identity data and public key, and signs the request with its private key. If the request is valid and the device is known to the system, a valid JWT authentication token is issued.

Unless the device is pre-authorized, the very first authentication request from a device will always result in a 'HTTP 401 Unauthorized' response. At the same time, the identity data is recorded for later inspection by the user, who can then explicitly accepts or rejects the device via the web GUI. A subsequent authentication request will reflect this decision.

Note that when the JWT expires, the device must renew the JWT by sending a new authentication request.

Body parameter

{
  "id_data": "{\"mac\":\"00:01:02:03:04:05\"}",
  "pubkey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzogVU7RGDilbsoUt/DdH\nVJvcepl0A5+xzGQ50cq1VE/Dyyy8Zp0jzRXCnnu9nu395mAFSZGotZVr+sWEpO3c\nyC3VmXdBZmXmQdZqbdD/GuixJOYfqta2ytbIUPRXFN7/I7sgzxnXWBYXYmObYvdP\nokP0mQanY+WKxp7Q16pt1RoqoAd0kmV39g13rFl35muSHbSBoAW3GBF3gO+mF5Ty\n1ddp/XcgLOsmvNNjY+2HOD5F/RX0fs07mWnbD7x+xz7KEKjF+H7ZpkqCwmwCXaf0\niyYyh1852rti3Afw4mDxuVSD7sd9ggvYMc0QHIpQNkD4YWOhNiE1AB0zH57VbUYG\nUwIDAQAB\n-----END PUBLIC KEY-----\n"
}

Parameters

Name In Type Required Description
X-MEN-Signature header string true Request signature.
body body AuthRequest true Authentication request.

Detailed descriptions

X-MEN-Signature: Request signature.

The request signature depends on the public key submitted in the AuthRequest. A summary of signature algorithms and format follows:

Type Digest Format Algorithm
RSA SHA256(AuthRequest) Base64(Signature) [RFC2313]
ECDSA SHA256(AuthRequest) Base64(ASN.1(SEQ{R, S})) [ANSI x9.62]
ED25519 AuthRequest Base64(Signature) [RFC8032]

Remark: For ECDSA, the signature constitutes two integers (R and S) in which case the binary signature is taken as the ASN.1 sequence of the two numbers in the given order.

Example responses

200 Response

"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NzYxMTkxMzYsImp0aSI6Ijg1NGIzMTA5LTQ4NjItNGEyNS1hMWZiLWYxMTE2MWNlN2E4NCIsImlzcyI6Ik1lbmRlciIsInN1YiI6IjlmNzM2YmNiMjhiZmFhOTg5YjVmNWUxNDA5ZGJmMGVhYzdhNjYxMjZiNjMyZDAzYWYwZmUzNGFjMjhiZjRhNzIifQ.PArg_WuoQkOiJ4kDoHYbQRjnxykeF1lIlsgJfUryhivnip2AHz5bkxxaxF20XTq9mIzSDonTSukfOtkaxJTZXjCMHjgh50iwa6_pUivIYWsIJW2O9t_M9T_SC-7Xu7IhE_iKQFb2NXxVfAG4nZKrheUM4MJBt8SxCawT2EOPopiLeIC6MOFBu_sPa9RsagKSZCRaLTBWVhmEGbfn19tLOX3Z06DZql61G-VY-YuyOlBjpEsCc4HiA1cXIdncCZKugrONOa44_m4yx0VsgRg4jCd2VO-Is-A96Jw3zkZshoD2cPXVSKAhFdhHja447ftuYYRq9kIQghKi3hfsPgyFZQ\n"

Missing or malformed request parameters or body.

{
  "error": "missing required parameter: id_data",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188f"
}

The device cannot be granted authentication. See the error message for details.

{
  "error": "device unauthorized",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Internal server error.

{
  "error": "internal error",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188d"
}

Responses

Status Meaning Description Schema
200 OK Authentication successful - a new JWT is issued and returned. string
400 Bad Request Missing or malformed request parameters or body. Error
401 Unauthorized The device cannot be granted authentication. See the error message for details. Error
500 Internal Server Error Internal server error. Error

Schemas

AuthRequest

{
  "id_data": "{\"mac\":\"00:01:02:03:04:05\"}",
  "pubkey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzogVU7RGDilbsoUt/DdH\nVJvcepl0A5+xzGQ50cq1VE/Dyyy8Zp0jzRXCnnu9nu395mAFSZGotZVr+sWEpO3c\nyC3VmXdBZmXmQdZqbdD/GuixJOYfqta2ytbIUPRXFN7/I7sgzxnXWBYXYmObYvdP\nokP0mQanY+WKxp7Q16pt1RoqoAd0kmV39g13rFl35muSHbSBoAW3GBF3gO+mF5Ty\n1ddp/XcgLOsmvNNjY+2HOD5F/RX0fs07mWnbD7x+xz7KEKjF+H7ZpkqCwmwCXaf0\niyYyh1852rti3Afw4mDxuVSD7sd9ggvYMc0QHIpQNkD4YWOhNiE1AB0zH57VbUYG\nUwIDAQAB\n-----END PUBLIC KEY-----\n"
}

Properties

Name Type Required Description
id_data string true Vendor-specific JSON representation of the device identity data (MACs, serial numbers, etc.).
pubkey string true The device's public key (PEM encoding), generated by the device or pre-provisioned by the vendor. Currently supported public algorithms are: RSA, ED25519 and ECDSA.
tenant_token string false Tenant token.

Error

{
  "error": "error description goes here",
  "request_id": "f7881e82-0492-49fb-b459-795654e71877"
}

Error descriptor.

Properties

Name Type Required Description
error string false Description of the error.
request_id string false Request ID (same as in X-MEN-RequestID header).

Device inventory

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

An API for uploading device attributes. Intended for use by devices.

Devices can upload vendor-specific attributes (software/hardware info, health checks, metrics, etc.) of various data types to the backend.

Base URLs:

Assign Attributes

Code samples

# You can also use wget
curl -X PATCH https://hosted.mender.io/api/devices/v1/inventory/device/attributes \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

PATCH https://hosted.mender.io/api/devices/v1/inventory/device/attributes HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '[
  {
    "name": "ip_addr",
    "value": "1.2.3.4",
    "description": "IP address"
  },
  {
    "name": "mac_addr",
    "value": "00.01:02:03:04:05",
    "description": "MAC address"
  }
]';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/devices/v1/inventory/device/attributes',
{
  method: 'PATCH',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.patch 'https://hosted.mender.io/api/devices/v1/inventory/device/attributes',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.patch('https://hosted.mender.io/api/devices/v1/inventory/device/attributes', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('PATCH','https://hosted.mender.io/api/devices/v1/inventory/device/attributes', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/devices/v1/inventory/device/attributes");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PATCH");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PATCH", "https://hosted.mender.io/api/devices/v1/inventory/device/attributes", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PATCH /device/attributes

Assign a set of attributes for a device

Saves the provided attribute set for the authenticated device. The device ID is retrieved from the authorization header.

This method has upsert semantics:

Body parameter

[
  {
    "name": "ip_addr",
    "value": "1.2.3.4",
    "description": "IP address"
  },
  {
    "name": "mac_addr",
    "value": "00.01:02:03:04:05",
    "description": "MAC address"
  }
]

Parameters

Name In Type Required Description
body body Attribute true A list of attribute descriptors.

Example responses

400 Response

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK Attributes were uploaded successfully. None
400 Bad Request Missing/malformed request parameters or body. Error
401 Unauthorized The device is not authenticated. None
500 Internal Server Error Internal server error. Error

Schemas

Attribute

{
  "name": "ip_addr_eth",
  "description": "Device IP address on ethernet interface",
  "value": "127.0.0.1"
}

Attribute descriptor.

Properties

Name Type Required Description
name string true A human readable, unique attribute ID, e.g. 'device_type', 'ip_addr', 'cpu_load', etc.
description string false Attribute description.
value string true The current value of the attribute.

Attribute type is implicit, inferred from the JSON type.

Supported types: number, string, array of numbers, array of strings.
Mixed type arrays are not allowed.

Error

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Error descriptor.

Properties

Name Type Required Description
error string false Description of the error.
request_id string false Request ID (same as in X-MEN-RequestID header).

Deployments

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

An API for device firmware deployments. Intended for use by devices.

Devices can get new updates and send information about current deployment status.

Base URLs:

Check Update

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/devices/v1/deployments/device/deployments/next?artifact_name=string&device_type=string \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/devices/v1/deployments/device/deployments/next?artifact_name=string&device_type=string HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/devices/v1/deployments/device/deployments/next?artifact_name=string&device_type=string',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/devices/v1/deployments/device/deployments/next',
  params: {
  'artifact_name' => 'string',
'device_type' => 'string'
}, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/devices/v1/deployments/device/deployments/next', params={
  'artifact_name': 'string',  'device_type': 'string'
}, headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/devices/v1/deployments/device/deployments/next', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/devices/v1/deployments/device/deployments/next?artifact_name=string&device_type=string");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/devices/v1/deployments/device/deployments/next", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /device/deployments/next

Get next update

On success, either an empty response or a DeploymentInstructions object is returned depending on whether there are any pending updates.

Parameters

Name In Type Required Description
artifact_name query string true currently installed artifact
device_type query string true Device type of device

Example responses

Successful response.

{
  "id": "w81s4fae-7dec-11d0-a765-00a0c91e6bf6",
  "artifact": {
    "artifact_name": "my-app-0.1",
    "source": {
      "uri": "https://aws.my_update_bucket.com/image_123",
      "expire": "2016-03-11T13:03:17.063493443Z"
    },
    "device_types_compatible": [
      "rspi",
      "rspi2",
      "rspi0"
    ]
  }
}

400 Response

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK Successful response. DeploymentInstructions
204 No Content No updates for device. None
400 Bad Request Invalid Request. Error
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

Check Update Depends

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/devices/v1/deployments/device/deployments/next \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

POST https://hosted.mender.io/api/devices/v1/deployments/device/deployments/next HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "device_type": "rspi",
  "artifact_name": "prototype-v1.0.0",
  "rootfs_image_checksum": "4d480539cdb23a4aee6330ff80673a5af92b7793eb1c57c4694532f96383b619"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/devices/v1/deployments/device/deployments/next',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.post 'https://hosted.mender.io/api/devices/v1/deployments/device/deployments/next',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.post('https://hosted.mender.io/api/devices/v1/deployments/device/deployments/next', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://hosted.mender.io/api/devices/v1/deployments/device/deployments/next', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/devices/v1/deployments/device/deployments/next");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/devices/v1/deployments/device/deployments/next", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /device/deployments/next

Get a next update satisfying dependencies

Returns the next update to be installed on the device. Next update will be chosen based on parameters provided in the request body. Request body should contain artifact_provides object.

Body parameter

{
  "device_type": "rspi",
  "artifact_name": "prototype-v1.0.0",
  "rootfs_image_checksum": "4d480539cdb23a4aee6330ff80673a5af92b7793eb1c57c4694532f96383b619"
}

Parameters

Name In Type Required Description
body body object true Key-value map of strings which describes the artifact(s) installed on the device and the
» additionalProperties body string false
» device_type body string true Device type of the device.
» artifact_name body string true Name of the currently installed artifact.

Detailed descriptions

body: Key-value map of strings which describes the artifact(s) installed on the device and the device itself. It is used to determine the next deployment. The keys device_type and artifact_name are mandatory, additional free-form key-value pairs can be specified.

Example responses

Successful response.

{
  "id": "w81s4fae-7dec-11d0-a765-00a0c91e6bf6",
  "artifact": {
    "artifact_name": "my-app-0.1",
    "source": {
      "uri": "https://aws.my_update_bucket.com/image_123",
      "expire": "2016-03-11T13:03:17.063493443Z"
    },
    "device_types_compatible": [
      "rspi",
      "rspi2",
      "rspi0"
    ]
  }
}

400 Response

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK Successful response. DeploymentInstructions
204 No Content No updates for device. None
400 Bad Request Invalid Request. Error
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

Update Deployment Status

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/devices/v1/deployments/device/deployments/{id}/status \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

PUT https://hosted.mender.io/api/devices/v1/deployments/device/deployments/{id}/status HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "status": "success"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/devices/v1/deployments/device/deployments/{id}/status',
{
  method: 'PUT',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.put 'https://hosted.mender.io/api/devices/v1/deployments/device/deployments/{id}/status',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.put('https://hosted.mender.io/api/devices/v1/deployments/device/deployments/{id}/status', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/devices/v1/deployments/device/deployments/{id}/status', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/devices/v1/deployments/device/deployments/{id}/status");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PUT");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "https://hosted.mender.io/api/devices/v1/deployments/device/deployments/{id}/status", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PUT /device/deployments/{id}/status

Update the device deployment status

Updates the status of a deployment on a particular device. Final status of the deployment is required to be set to indicate the success or failure of the installation process. The status can not be changed when deployment status is set to aborted. Reporting of intermediate steps such as installing, downloading, rebooting is optional.

Body parameter

{
  "status": "success"
}

Parameters

Name In Type Required Description
id path string true Deployment identifier.
body body DeploymentStatus true Deployment status.

Example responses

400 Response

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content Status updated successfully. None
400 Bad Request Invalid Request. Error
404 Not Found Not Found. Error
409 Conflict Status already set to aborted. None
500 Internal Server Error Internal Server Error. Error

Report Deployment Log

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/devices/v1/deployments/device/deployments/{id}/log \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

PUT https://hosted.mender.io/api/devices/v1/deployments/device/deployments/{id}/log HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "messages": [
    {
      "timestamp": "2016-03-11T13:03:17.063493443Z",
      "level": "INFO",
      "message": "OK"
    },
    {
      "timestamp": "2016-03-11T13:03:18.023765782Z",
      "level": "DEBUG",
      "message": "successfully updated."
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/devices/v1/deployments/device/deployments/{id}/log',
{
  method: 'PUT',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.put 'https://hosted.mender.io/api/devices/v1/deployments/device/deployments/{id}/log',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.put('https://hosted.mender.io/api/devices/v1/deployments/device/deployments/{id}/log', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/devices/v1/deployments/device/deployments/{id}/log', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/devices/v1/deployments/device/deployments/{id}/log");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PUT");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "https://hosted.mender.io/api/devices/v1/deployments/device/deployments/{id}/log", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PUT /device/deployments/{id}/log

Upload the device deployment log

Set the log of a selected deployment. Messages are split by line in the payload.

Body parameter

{
  "messages": [
    {
      "timestamp": "2016-03-11T13:03:17.063493443Z",
      "level": "INFO",
      "message": "OK"
    },
    {
      "timestamp": "2016-03-11T13:03:18.023765782Z",
      "level": "DEBUG",
      "message": "successfully updated."
    }
  ]
}

Parameters

Name In Type Required Description
id path string true Deployment identifier.
body body DeploymentLog true Deployment log

Example responses

400 Response

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content The deployment log uploaded successfully. None
400 Bad Request Invalid Request. Error
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

Schemas

Error

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Error descriptor.

Properties

Name Type Required Description
error string false Description of the error.
request_id string false Request ID (same as in X-MEN-RequestID header).

DeploymentStatus

{
  "status": "success"
}

Properties

Name Type Required Description
status string true
substate string false Additional state information

Enumerated Values

Property Value
status installing
status downloading
status rebooting
status success
status failure
status already-installed

DeploymentInstructions

{
  "id": "w81s4fae-7dec-11d0-a765-00a0c91e6bf6",
  "artifact": {
    "artifact_name": "my-app-0.1",
    "source": {
      "uri": "https://aws.my_update_bucket.com/image_123",
      "expire": "2016-03-11T13:03:17.063493443Z"
    },
    "device_types_compatible": [
      "rspi",
      "rspi2",
      "rspi0"
    ]
  }
}

Properties

Name Type Required Description
id string true Deployment ID (device unique)
artifact object true
» source object true
»» uri string(url) false URL to fetch the artifact from
»» expire string(date-time) false URL expiration time
» device_types_compatible [string] true Compatible device types
» artifact_name string true

DeploymentLog

{
  "messages": [
    {
      "timestamp": "2016-03-11T13:03:17.063493443Z",
      "level": "INFO",
      "message": "OK"
    },
    {
      "timestamp": "2016-03-11T13:03:18.023765782Z",
      "level": "DEBUG",
      "message": "successfully updated."
    }
  ]
}

Properties

Name Type Required Description
messages [object] true
» timestamp string(date-time) true
» level string true
» message string true

Management APIs

Device authentication

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

An API for device authentication handling.

Base URLs:

List Devices

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/devauth/devices \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v2/devauth/devices HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v2/devauth/devices',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v2/devauth/devices',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v2/devauth/devices', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v2/devauth/devices', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v2/devauth/devices");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v2/devauth/devices", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /devices

List devices sorted by age and optionally filter on device status.

Parameters

Name In Type Required Description
status query string false Device status filter. If not specified, all devices are listed.
page query integer false Results page number
per_page query integer false Maximum number of results per page.

Detailed descriptions

status: Device status filter. If not specified, all devices are listed.

Enumerated Values

Parameter Value
status pending
status accepted
status rejected
status preauthorized
status noauth

Example responses

200 Response

[
  {
    "id": "string",
    "identity_data": {
      "mac": "00:01:02:03:04:05",
      "sku": "My Device 1",
      "sn": "SN1234567890"
    },
    "status": "pending",
    "created_ts": "2019-08-24T14:15:22Z",
    "updated_ts": "2019-08-24T14:15:22Z",
    "auth_sets": [
      {
        "id": "string",
        "pubkey": "string",
        "identity_data": {
          "mac": "00:01:02:03:04:05",
          "sku": "My Device 1",
          "sn": "SN1234567890"
        },
        "status": "pending",
        "ts": "2019-08-24T14:15:22Z"
      }
    ],
    "decommissioning": true
  }
]

Responses

Status Meaning Description Schema
200 OK An array of devices. Inline
400 Bad Request Missing/malformed request params. Error
500 Internal Server Error Unexpected error Error

Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [Device] false
» id string false Mender assigned Device ID.
» identity_data IdentityData false Device identity attributes, in the form of a JSON structure.

The attributes are completely vendor-specific, the provided ones are just an example.
In reference implementation structure contains vendor-selected fields,
such as MACs, serial numbers, etc.
»» mac string false MAC address.
»» sku string false Stock keeping unit.
»» sn string false Serial number.
» status string false
» created_ts string(date-time) false Created timestamp
» updated_ts string(date-time) false Updated timestamp
» auth_sets [AuthSet] false [Authentication data set]
»» id string false Authentication data set ID.
»» pubkey string false The device's public key (PEM encoding), generated by the device or pre-provisioned by the vendor. Currently supported public algorithms are: RSA, ED25519 and ECDSA.
»» identity_data IdentityData false Device identity attributes, in the form of a JSON structure.

The attributes are completely vendor-specific, the provided ones are just an example.
In reference implementation structure contains vendor-selected fields,
such as MACs, serial numbers, etc.
»» status string false
»» ts string(date-time) false Created timestamp
» decommissioning boolean false Devices that are part of ongoing decomissioning process will return True

Enumerated Values

Property Value
status pending
status accepted
status rejected
status preauthorized
status noauth
status pending
status accepted
status rejected
status preauthorized
status noauth

Response Headers

Status Header Type Format Description
200 Link string Standard header, we support 'first', 'next', and 'prev'.

Preauthorize

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/devauth/devices \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

POST https://hosted.mender.io/api/management/v2/devauth/devices HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "identity_data": {
    "mac": "00:01:02:03:04:05",
    "sku": "My Device 1",
    "sn": "SN1234567890"
  },
  "pubkey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzogVU7RGDilbsoUt/DdH\nVJvcepl0A5+xzGQ50cq1VE/Dyyy8Zp0jzRXCnnu9nu395mAFSZGotZVr+sWEpO3c\nyC3VmXdBZmXmQdZqbdD/GuixJOYfqta2ytbIUPRXFN7/I7sgzxnXWBYXYmObYvdP\nokP0mQanY+WKxp7Q16pt1RoqoAd0kmV39g13rFl35muSHbSBoAW3GBF3gO+mF5Ty\n1ddp/XcgLOsmvNNjY+2HOD5F/RX0fs07mWnbD7x+xz7KEKjF+H7ZpkqCwmwCXaf0\niyYyh1852rti3Afw4mDxuVSD7sd9ggvYMc0QHIpQNkD4YWOhNiE1AB0zH57VbUYG\nUwIDAQAB\n-----END PUBLIC KEY-----\n"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v2/devauth/devices',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v2/devauth/devices',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.post('https://hosted.mender.io/api/management/v2/devauth/devices', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v2/devauth/devices', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v2/devauth/devices");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v2/devauth/devices", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /devices

Submit a preauthorized device.

Authorize a device identity with the server backend. On success the device identity is marked as 'preauthorized', and once the device connects and sends it's first authentication request the device automatically become 'accepted' without explicit user intervention.

Body parameter

{
  "identity_data": {
    "mac": "00:01:02:03:04:05",
    "sku": "My Device 1",
    "sn": "SN1234567890"
  },
  "pubkey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzogVU7RGDilbsoUt/DdH\nVJvcepl0A5+xzGQ50cq1VE/Dyyy8Zp0jzRXCnnu9nu395mAFSZGotZVr+sWEpO3c\nyC3VmXdBZmXmQdZqbdD/GuixJOYfqta2ytbIUPRXFN7/I7sgzxnXWBYXYmObYvdP\nokP0mQanY+WKxp7Q16pt1RoqoAd0kmV39g13rFl35muSHbSBoAW3GBF3gO+mF5Ty\n1ddp/XcgLOsmvNNjY+2HOD5F/RX0fs07mWnbD7x+xz7KEKjF+H7ZpkqCwmwCXaf0\niyYyh1852rti3Afw4mDxuVSD7sd9ggvYMc0QHIpQNkD4YWOhNiE1AB0zH57VbUYG\nUwIDAQAB\n-----END PUBLIC KEY-----\n"
}

Parameters

Name In Type Required Description
body body PreAuthSet true Preauthentication request.

Example responses

400 Response

{
  "error": "string"
}

Responses

Status Meaning Description Schema
201 Created Device submitted. None
400 Bad Request Missing/malformed request params. Error
409 Conflict Device already exists. Response contains conflicting device. Device
500 Internal Server Error Unexpected error Error

Response Headers

Status Header Type Format Description
201 Location string URL of the newly created user-ID.

Get Device

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/devauth/devices/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v2/devauth/devices/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v2/devauth/devices/{id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v2/devauth/devices/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v2/devauth/devices/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v2/devauth/devices/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v2/devauth/devices/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v2/devauth/devices/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /devices/{id}

Get a particular device.

Parameters

Name In Type Required Description
id path string true Device identifier

Example responses

200 Response

{
  "id": "string",
  "identity_data": {
    "mac": "00:01:02:03:04:05",
    "sku": "My Device 1",
    "sn": "SN1234567890"
  },
  "status": "pending",
  "created_ts": "2019-08-24T14:15:22Z",
  "updated_ts": "2019-08-24T14:15:22Z",
  "auth_sets": [
    {
      "id": "string",
      "pubkey": "string",
      "identity_data": {
        "mac": "00:01:02:03:04:05",
        "sku": "My Device 1",
        "sn": "SN1234567890"
      },
      "status": "pending",
      "ts": "2019-08-24T14:15:22Z"
    }
  ],
  "decommissioning": true
}

Responses

Status Meaning Description Schema
200 OK Device found. Device
404 Not Found Device not found. Error
500 Internal Server Error Unexpected error Error

Decommission device

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v2/devauth/devices/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

DELETE https://hosted.mender.io/api/management/v2/devauth/devices/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v2/devauth/devices/{id}',
{
  method: 'DELETE',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.delete 'https://hosted.mender.io/api/management/v2/devauth/devices/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.delete('https://hosted.mender.io/api/management/v2/devauth/devices/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('DELETE','https://hosted.mender.io/api/management/v2/devauth/devices/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v2/devauth/devices/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("DELETE");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "https://hosted.mender.io/api/management/v2/devauth/devices/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /devices/{id}

Remove device and associated authentication set

Parameters

Name In Type Required Description
id path string true Device identifier.

Example responses

404 Response

{
  "error": "string"
}

Responses

Status Meaning Description Schema
204 No Content Device decommissioned. None
404 Not Found Device not found Error
500 Internal Server Error Internal server error. Error

Reject authentication

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid} \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

DELETE https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}',
{
  method: 'DELETE',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.delete 'https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.delete('https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('DELETE','https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("DELETE");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /devices/{id}/auth/{aid}

Remove the device authentication set

Removes the device authentication set. Removing 'accepted' authentication set is equivalent to rejecting device and removing authentication set. If there is only one authentication set for the device and the device is 'preauthorized' then the device will also be deleted.

Parameters

Name In Type Required Description
id path string true Device identifier.
aid path string true Authentication data set identifier.

Example responses

404 Response

{
  "error": "string"
}

Responses

Status Meaning Description Schema
204 No Content Device authentication set deleted. None
404 Not Found Device authentication set not found Error
500 Internal Server Error Internal server error. Error

Set Authentication Status

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}/status \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

PUT https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}/status HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "status": "accepted"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}/status',
{
  method: 'PUT',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}/status',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.put('https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}/status', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}/status', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}/status");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PUT");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}/status", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PUT /devices/{id}/auth/{aid}/status

Update the device authentication set status

Sets the status of a authentication data set of selected value. Valid state transitions:

Body parameter

{
  "status": "accepted"
}

Parameters

Name In Type Required Description
id path string true Device identifier.
aid path string true Authentication data set identifier.
body body Status true New status.

Example responses

400 Response

{
  "error": "string"
}

Responses

Status Meaning Description Schema
204 No Content The device authentication data set status was successfully updated. None
400 Bad Request Bad request. Error
404 Not Found The device was not found. Error
422 Unprocessable Entity Request cannot be fulfilled e.g. due to exceeded limit on maximum accepted devices (see error message). Error
500 Internal Server Error Internal server error. Error

Get Authentication Status

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}/status \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}/status HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}/status',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}/status',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}/status', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}/status', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}/status");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v2/devauth/devices/{id}/auth/{aid}/status", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /devices/{id}/auth/{aid}/status

Get the device authentication set status

Parameters

Name In Type Required Description
id path string true Device identifier.
aid path string true Authentication data set identifier.

Example responses

successful response - the device's authentication set status is returned.

{
  "status": "accepted"
}

404 Response

{
  "error": "string"
}

Responses

Status Meaning Description Schema
200 OK successful response - the device's authentication set status is returned. Status
404 Not Found The device was not found. Error
500 Internal Server Error Internal server error. Error

Count Devices

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/devauth/devices/count \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v2/devauth/devices/count HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v2/devauth/devices/count',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v2/devauth/devices/count',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v2/devauth/devices/count', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v2/devauth/devices/count', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v2/devauth/devices/count");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v2/devauth/devices/count", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /devices/count

Count number of devices, optionally filtered by status.

Parameters

Name In Type Required Description
status query string false Device status filter, one of 'pending', 'accepted', 'rejected', 'noauth'. Default is 'all devices'.

Detailed descriptions

status: Device status filter, one of 'pending', 'accepted', 'rejected', 'noauth'. Default is 'all devices'.

Example responses

200 Response

{
  "count": 42
}

Responses

Status Meaning Description Schema
200 OK Device count. Count
400 Bad Request Missing/malformed request params. Error
500 Internal Server Error Unexpected error Error

Revoke API Token

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v2/devauth/tokens/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

DELETE https://hosted.mender.io/api/management/v2/devauth/tokens/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v2/devauth/tokens/{id}',
{
  method: 'DELETE',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.delete 'https://hosted.mender.io/api/management/v2/devauth/tokens/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.delete('https://hosted.mender.io/api/management/v2/devauth/tokens/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('DELETE','https://hosted.mender.io/api/management/v2/devauth/tokens/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v2/devauth/tokens/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("DELETE");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "https://hosted.mender.io/api/management/v2/devauth/tokens/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /tokens/{id}

Revoke JWT with given id

Deletes the token, effectively revoking it. The device must apply for a new one with a new authentication request. The token 'id' corresponds to the standard 'jti' claim.

Parameters

Name In Type Required Description
id path string true Unique token identifier('jti').

Example responses

404 Response

{
  "error": "string"
}

Responses

Status Meaning Description Schema
204 No Content The token was successfully deleted. None
404 Not Found The token was not found. Error
500 Internal Server Error Internal server error. Error

Get Device Limit

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/devauth/limits/max_devices \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v2/devauth/limits/max_devices HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v2/devauth/limits/max_devices',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v2/devauth/limits/max_devices',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v2/devauth/limits/max_devices', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v2/devauth/limits/max_devices', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v2/devauth/limits/max_devices");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v2/devauth/limits/max_devices", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /limits/max_devices

Obtain limit of accepted devices.

Example responses

200 Response

{
  "limit": 123
}

Responses

Status Meaning Description Schema
200 OK Usage statistics and limits. Limit
500 Internal Server Error Internal server error. Error

Schemas

Status

{
  "status": "accepted"
}

Admission status of the device.

Properties

Name Type Required Description
status string true

Enumerated Values

Property Value
status pending
status accepted
status rejected
status preauthorized

Limit

{
  "limit": 123
}

Limit definition

Properties

Name Type Required Description
limit integer true

Device

{
  "id": "string",
  "identity_data": {
    "mac": "00:01:02:03:04:05",
    "sku": "My Device 1",
    "sn": "SN1234567890"
  },
  "status": "pending",
  "created_ts": "2019-08-24T14:15:22Z",
  "updated_ts": "2019-08-24T14:15:22Z",
  "auth_sets": [
    {
      "id": "string",
      "pubkey": "string",
      "identity_data": {
        "mac": "00:01:02:03:04:05",
        "sku": "My Device 1",
        "sn": "SN1234567890"
      },
      "status": "pending",
      "ts": "2019-08-24T14:15:22Z"
    }
  ],
  "decommissioning": true
}

Properties

Name Type Required Description
id string false Mender assigned Device ID.
identity_data IdentityData false Device identity attributes, in the form of a JSON structure.

The attributes are completely vendor-specific, the provided ones are just an example.
In reference implementation structure contains vendor-selected fields,
such as MACs, serial numbers, etc.
status string false
created_ts string(date-time) false Created timestamp
updated_ts string(date-time) false Updated timestamp
auth_sets [AuthSet] false [Authentication data set]
decommissioning boolean false Devices that are part of ongoing decomissioning process will return True

Enumerated Values

Property Value
status pending
status accepted
status rejected
status preauthorized
status noauth

AuthSet

{
  "id": "string",
  "pubkey": "string",
  "identity_data": {
    "mac": "00:01:02:03:04:05",
    "sku": "My Device 1",
    "sn": "SN1234567890"
  },
  "status": "pending",
  "ts": "2019-08-24T14:15:22Z"
}

Authentication data set

Properties

Name Type Required Description
id string false Authentication data set ID.
pubkey string false The device's public key (PEM encoding), generated by the device or pre-provisioned by the vendor. Currently supported public algorithms are: RSA, ED25519 and ECDSA.
identity_data IdentityData false Device identity attributes, in the form of a JSON structure.

The attributes are completely vendor-specific, the provided ones are just an example.
In reference implementation structure contains vendor-selected fields,
such as MACs, serial numbers, etc.
status string false
ts string(date-time) false Created timestamp

Enumerated Values

Property Value
status pending
status accepted
status rejected
status preauthorized
status noauth

Count

{
  "count": 42
}

Counter type

Properties

Name Type Required Description
count integer false The count of requested items.

Error

{
  "error": "string"
}

Error descriptor

Properties

Name Type Required Description
error string false Description of the error

PreAuthSet

{
  "identity_data": {
    "mac": "00:01:02:03:04:05",
    "sku": "My Device 1",
    "sn": "SN1234567890"
  },
  "pubkey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzogVU7RGDilbsoUt/DdH\nVJvcepl0A5+xzGQ50cq1VE/Dyyy8Zp0jzRXCnnu9nu395mAFSZGotZVr+sWEpO3c\nyC3VmXdBZmXmQdZqbdD/GuixJOYfqta2ytbIUPRXFN7/I7sgzxnXWBYXYmObYvdP\nokP0mQanY+WKxp7Q16pt1RoqoAd0kmV39g13rFl35muSHbSBoAW3GBF3gO+mF5Ty\n1ddp/XcgLOsmvNNjY+2HOD5F/RX0fs07mWnbD7x+xz7KEKjF+H7ZpkqCwmwCXaf0\niyYyh1852rti3Afw4mDxuVSD7sd9ggvYMc0QHIpQNkD4YWOhNiE1AB0zH57VbUYG\nUwIDAQAB\n-----END PUBLIC KEY-----\n"
}

Properties

Name Type Required Description
identity_data IdentityData true Device identity attributes, in the form of a JSON structure.

The attributes are completely vendor-specific, the provided ones are just an example.
In reference implementation structure contains vendor-selected fields,
such as MACs, serial numbers, etc.
pubkey string true The device's public key (PEM encoding), generated by the device or pre-provisioned by the vendor. Currently supported public algorithms are: RSA, ED25519 and ECDSA.

IdentityData

{
  "mac": "00:01:02:03:04:05",
  "sku": "My Device 1",
  "sn": "SN1234567890"
}

Device identity attributes, in the form of a JSON structure.

The attributes are completely vendor-specific, the provided ones are just an example. In reference implementation structure contains vendor-selected fields, such as MACs, serial numbers, etc.

Properties

Name Type Required Description
mac string false MAC address.
sku string false Stock keeping unit.
sn string false Serial number.

Device inventory

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

An API for device attribute management and device grouping. Intended for use by the web GUI.

Devices can upload vendor-specific attributes (software/hardware info, health checks, metrics, etc.) of various data types to the backend.

This API enables the user to:

Base URLs:

List Device Inventories

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/inventory/devices \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/inventory/devices HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/inventory/devices',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/inventory/devices',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/inventory/devices', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/inventory/devices', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/inventory/devices");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/inventory/devices", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /devices

List devices inventories

Returns a paged collection of devices and their attributes. Accepts optional search and sort parameters.

Searching Searching by attributes values is accomplished by appending attribute name/value pairs to the query string, e.g.: GET /devices?attr_name_1=foo&attr_name_2=100

Parameters

Name In Type Required Description
page query number(integer) false Starting page.
per_page query number(integer) false Maximum number of results per page.
sort query string(attr[:ord][,attr[:ord]...]) false Sort devices by attribute.
has_group query boolean false Limit result to devices assigned to a group.
group query string false Limits result to devices in the given group.

Detailed descriptions

sort: Sort devices by attribute. The parameter is formatted as a comma-separated list of attribute names and sort order.

The order direction (ord) must be either asc or desc for ascending and descending respectively. Defaults to desc if not specified.

For example: ?sort=attr1:asc,attr2:desc will sort by 'attr1' ascending, and then by 'attr2' descending.

Example responses

Successful response.

[
  {
    "id": "291ae0e5956c69c2267489213df4459d19ed48a806603def19d417d004a4b67e",
    "attributes": [
      {
        "name": "ip_addr",
        "scope": "inventory",
        "value": "1.2.3.4",
        "description": "IP address"
      },
      {
        "name": "mac_addr",
        "scope": "inventory",
        "value": "00.01:02:03:04:05",
        "description": "MAC address"
      }
    ],
    "updated_ts": "2016-10-03T16:58:51.639Z"
  },
  {
    "id": "76f40e5956c699e327489213df4459d1923e1a806603def19d417d004a4a3ef",
    "attributes": [
      {
        "name": "mac",
        "scope": "inventory",
        "value": "00:01:02:03:04:05",
        "description": "MAC address"
      }
    ],
    "updated_ts": "2016-10-04T18:24:21.432Z"
  }
]

400 Response

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK Successful response. Inline
400 Bad Request Missing or malformed request parameters. Error
500 Internal Server Error Internal error. Error

Response Schema

Status Code 200

ListOfDevices

Name Type Required Restrictions Description
ListOfDevices [DeviceInventory] false
» id string false Mender-assigned unique device ID.
» updated_ts string false Timestamp of the most recent attribute update.
» attributes [Attribute] false A list of attribute descriptors.
»» name string true A human readable, unique attribute ID, e.g. 'device_type', 'ip_addr', 'cpu_load', etc.
»» description string false Attribute description.
»» value string true The current value of the attribute.

Attribute type is implicit, inferred from the JSON type.

Supported types: number, string, array of numbers, array of strings.
Mixed type arrays are not allowed.

Response Headers

Status Header Type Format Description
200 Link string Standard page navigation header, supported relations: 'first', 'next', and 'prev'.
200 X-Total-Count string Total number of devices found

Get Device Inventory

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/inventory/devices/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/inventory/devices/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/inventory/devices/{id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/inventory/devices/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/inventory/devices/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/inventory/devices/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/inventory/devices/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/inventory/devices/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /devices/{id}

Get a selected device's inventory

Parameters

Name In Type Required Description
id path string true Device identifier.

Example responses

Successful response - the device was found.

{
  "id": "291ae0e5956c69c2267489213df4459d19ed48a806603def19d417d004a4b67e",
  "attributes": [
    {
      "name": "ip_addr",
      "scope": "inventory",
      "value": "1.2.3.4",
      "description": "IP address"
    },
    {
      "name": "mac_addr",
      "scope": "inventory",
      "value": "00.01:02:03:04:05",
      "description": "MAC address"
    }
  ],
  "updated_ts": "2016-10-03T16:58:51.639Z"
}

404 Response

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK Successful response - the device was found. DeviceInventory
404 Not Found The device was not found. Error
500 Internal Server Error Internal server error. Error

Delete Device Inventory

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v1/inventory/devices/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

DELETE https://hosted.mender.io/api/management/v1/inventory/devices/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/inventory/devices/{id}',
{
  method: 'DELETE',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.delete 'https://hosted.mender.io/api/management/v1/inventory/devices/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.delete('https://hosted.mender.io/api/management/v1/inventory/devices/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('DELETE','https://hosted.mender.io/api/management/v1/inventory/devices/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/inventory/devices/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("DELETE");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "https://hosted.mender.io/api/management/v1/inventory/devices/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /devices/{id}

Remove selected device's inventory

Parameters

Name In Type Required Description
id path string true Device identifier.

Example responses

500 Response

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content Device removed None
500 Internal Server Error Internal server error. Error

Get Device Group

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /devices/{id}/group

Get a selected device's group

Parameters

Name In Type Required Description
id path string true Device identifier.

Example responses

200 Response

{
  "group": "staging"
}

Responses

Status Meaning Description Schema
200 OK Successful response. If the device is not assigned to any group, the 'group' field will be set to 'null'. Group
400 Bad Request Missing or malformed request params or body. See the error message for details. None
404 Not Found The device was not found. Error
500 Internal Server Error Internal server error. Error

Assign Group

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

PUT https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "group": "staging"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group',
{
  method: 'PUT',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.put('https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PUT");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PUT /devices/{id}/group

Add a device to a group

Adds a device to a group.

Note that a given device can belong to at most one group. If a device already belongs to some group, it will be moved to the selected one.

Body parameter

{
  "group": "staging"
}

Parameters

Name In Type Required Description
id path string true Device identifier.
body body Group true Group descriptor.

Example responses

404 Response

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content Success - the device was added to the group. None
400 Bad Request Missing or malformed request params or body. See the error message for details. None
404 Not Found The device was not found. Error
500 Internal Server Error Internal server error. Error

Clear Group

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group/{name} \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

DELETE https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group/{name} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group/{name}',
{
  method: 'DELETE',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.delete 'https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group/{name}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.delete('https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group/{name}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('DELETE','https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group/{name}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group/{name}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("DELETE");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "https://hosted.mender.io/api/management/v1/inventory/devices/{id}/group/{name}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /devices/{id}/group/{name}

Remove a device from a group

Removes the device with identifier 'id' from the group 'group'.

Parameters

Name In Type Required Description
id path string true Device identifier.
name path string true Group name.

Example responses

404 Response

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content The device was successfully removed from the group. None
404 Not Found The device was not found or doesn't belong to the group. Error
500 Internal Server Error Internal error. Error

List Groups

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/inventory/groups \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/inventory/groups HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/inventory/groups',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/inventory/groups',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/inventory/groups', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/inventory/groups', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/inventory/groups");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/inventory/groups", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /groups

List all groups existing device groups

Parameters

Name In Type Required Description
status query string false Show groups for devices with the given auth set status.

Example responses

Successful response.

[
  "staging",
  "testing",
  "production"
]

500 Response

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK Successful response. Inline
500 Internal Server Error Internal server error. Error

Response Schema

Status Code 200

Name Type Required Restrictions Description
» ListOfGroupNames string false Group name

Get Devices in Group

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /groups/{name}/devices

List the devices belonging to a given group

Parameters

Name In Type Required Description
page query integer false Starting page.
per_page query integer false Maximum number of results per page.
name path string true Group name.

Example responses

200 Response

[
  "string"
]

Responses

Status Meaning Description Schema
200 OK Successful response Inline
400 Bad Request Invalid request parameters. Error
404 Not Found The group was not found. Error
500 Internal Server Error Internal server error. Error

Response Schema

Status Code 200

ListOfIDs

Name Type Required Restrictions Description
ListOfIDs [string] false

Response Headers

Status Header Type Format Description
200 Link string Standard header, we support 'first', 'next', and 'prev'.
200 X-Total-Count string Custom header indicating the total number of devices in the given group

Add Devices to Group

Code samples

# You can also use wget
curl -X PATCH https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

PATCH https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '[
  "string"
]';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices',
{
  method: 'PATCH',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.patch 'https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.patch('https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('PATCH','https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PATCH");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PATCH", "https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PATCH /groups/{name}/devices

Add devices to group

Appends the list of devices in the request body to the given group. For devices already present in the group the operation has no effect.

Body parameter

[
  "string"
]

Parameters

Name In Type Required Description
name path string true Group name.
body body array[string] true JSON list of device IDs to append to the group.

Example responses

Successful response

{
  "updated_count": 2,
  "matched_count": 3
}

400 Response

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK Successful response Inline
400 Bad Request Invalid request schema. Error
404 Not Found The group was not found. Error
500 Internal Server Error Internal server error. Error

Response Schema

Status Code 200

*JSON object listing how many devices were updated. *

Name Type Required Restrictions Description
» updated_count number true Number of devices listed that changed group.
» matched_count number true Number of devices listed that matched a valid device id internally.

Remove Devices from Group

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

DELETE https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '[
  "string"
]';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices',
{
  method: 'DELETE',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.delete 'https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.delete('https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('DELETE','https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("DELETE");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "https://hosted.mender.io/api/management/v1/inventory/groups/{name}/devices", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /groups/{name}/devices

Clear devices' group

Removes a list of devices from their respective groups. This API provides a bulk alternative to DELETE /devices/{id}/group/{name} for managing device groups.

Body parameter

[
  "string"
]

Parameters

Name In Type Required Description
name path string true Group name.
body body array[string] true JSON list of device IDs to append to the group.

Example responses

Successful response

{
  "updated_count": 2
}

400 Response

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK Successful response Inline
400 Bad Request Invalid request schema. Error
404 Not Found The group was not found. Error
500 Internal Server Error Internal server error. Error

Response Schema

Status Code 200

*JSON object listing how many devices were updated. *

Name Type Required Restrictions Description
» updated_count number true Number of devices for which the group was cleared sucessfully.

Schemas

Attribute

{
  "name": "ip_addr_eth",
  "description": "Device IP address on ethernet interface",
  "value": "127.0.0.1"
}

Attribute descriptor.

Properties

Name Type Required Description
name string true A human readable, unique attribute ID, e.g. 'device_type', 'ip_addr', 'cpu_load', etc.
description string false Attribute description.
value string true The current value of the attribute.

Attribute type is implicit, inferred from the JSON type.

Supported types: number, string, array of numbers, array of strings.
Mixed type arrays are not allowed.

DeviceInventory

{
  "id": "291ae0e5956c69c2267489213df4459d19ed48a806603def19d417d004a4b67e",
  "attributes": [
    {
      "name": "ip_addr",
      "value": "1.2.3.4",
      "description": "IP address"
    },
    {
      "name": "mac_addr",
      "value": "00.01:02:03:04:05",
      "description": "MAC address"
    }
  ],
  "updated_ts": "2016-10-03T16:58:51.639Z"
}

Properties

Name Type Required Description
id string false Mender-assigned unique device ID.
updated_ts string false Timestamp of the most recent attribute update.
attributes [Attribute] false A list of attribute descriptors.

Group

{
  "group": "staging"
}

Properties

Name Type Required Description
group string true Device group.

Error

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Error descriptor.

Properties

Name Type Required Description
error string false Description of the error.
request_id string false Request ID (same as in X-MEN-RequestID header).

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

An API for inventory-based filters management and device search. It is intended for use by the web GUI.

Devices can upload vendor-specific attributes (software/hardware info, health checks, metrics, etc.) of various data types to the backend as scoped attributes.

This API enables the user to:

Base URLs:

Search Device Inventories

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/inventory/filters/search \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

POST https://hosted.mender.io/api/management/v2/inventory/filters/search HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "page": 1,
  "per_page": 20,
  "filters": [
    {
      "type": "$eq",
      "attribute": "serial_no",
      "scope": "inventory",
      "value": "123456789"
    }
  ],
  "sort": [
    {
      "attribute": "serial_no",
      "scope": "inventory",
      "order": "asc"
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v2/inventory/filters/search',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v2/inventory/filters/search',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.post('https://hosted.mender.io/api/management/v2/inventory/filters/search', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v2/inventory/filters/search', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v2/inventory/filters/search");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v2/inventory/filters/search", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /filters/search

Search devices based on inventory attributes

Returns a paged collection of devices and their attributes.

If multiple filter predicates are specified, the filters are combined using boolean and operator.

This operation is only available in our commercial offering and requires you to be on the following plans:

Body parameter

{
  "page": 1,
  "per_page": 20,
  "filters": [
    {
      "type": "$eq",
      "attribute": "serial_no",
      "scope": "inventory",
      "value": "123456789"
    }
  ],
  "sort": [
    {
      "attribute": "serial_no",
      "scope": "inventory",
      "order": "asc"
    }
  ]
}

Parameters

Name In Type Required Description
body body object false The search and sort parameters of the filter
» page body number(integer) false Starting page.
» per_page body number(integer) false Maximum number of results per page.
» filters body [FilterPredicate] false List of filter predicates.
»» scope body string true Attribute scope.
»» attribute body string true Attribute name.
»» type body string true Type or operator of the filter predicate.
»» value body string true The value of the attribute to be used in filtering.
» sort body [SortCriteria] false List of ordered sort criteria
»» scope body string true Attribute scope.
»» attribute body string true Attribute name.
»» order body string true Order direction, ascending ("asc") or descending ("desc").

Detailed descriptions

»» type: Type or operator of the filter predicate.

Operator Name Argument type
$eq Equal (==) any
$ne Not equal (!=) any
$gt Greater than (>) any
$gte Greater than or equal (>=) any
$lt Less than (<) any
$lte Less than or equal (<=) any
$exists Attribute exists bool
$in Is an element of array
$nin Is not an element of array
$regex Regex filter string

»» value: The value of the attribute to be used in filtering. Attribute type is implicit, inferred from the JSON type.

The $exists operator expects a boolean value: true means the specified attribute exists, false means the specified attribute doesn't exist.

The $regex operator expects a string as a Perl compatible regular expression (PCRE), automatically anchored by ^. If the regular expression is not valid, the filter will produce no results. If you need to specify options and flags, you can provide the full regex in the format of /regex/flags, for example /[a-z]+/i.

Enumerated Values

Parameter Value
»» type $eq
»» type $gt
»» type $gte
»» type $in
»» type $lt
»» type $lte
»» type $ne
»» type $nin
»» type $exists
»» type $regex
»» order asc
»» order desc

Example responses

Successful response.

[
  {
    "id": "291ae0e5956c69c2267489213df4459d19ed48a806603def19d417d004a4b67e",
    "attributes": [
      {
        "name": "ip_addr",
        "scope": "inventory",
        "value": "1.2.3.4",
        "description": "IP address"
      },
      {
        "name": "mac_addr",
        "scope": "inventory",
        "value": "00.01:02:03:04:05",
        "description": "MAC address"
      }
    ],
    "updated_ts": "2016-10-03T16:58:51.639Z"
  },
  {
    "id": "76f40e5956c699e327489213df4459d1923e1a806603def19d417d004a4a3ef",
    "attributes": [
      {
        "name": "mac",
        "scope": "identity",
        "value": "00:01:02:03:04:05",
        "description": "MAC address"
      }
    ],
    "updated_ts": "2016-10-04T18:24:21.432Z"
  }
]

400 Response

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK Successful response. Inline
400 Bad Request Missing or malformed request parameters. See error for details. Error
500 Internal Server Error Internal error. Error

Response Schema

Status Code 200

ListOfDevices

Name Type Required Restrictions Description
ListOfDevices [DeviceInventory] false
» id string false Mender-assigned unique ID.
» updated_ts string false Timestamp of the most recent attribute update.
» attributes [Attribute] false A list of attribute descriptors.
»» name string true A human readable, unique attribute ID, e.g. 'device_type', 'ip_addr', 'cpu_load', etc.
»» scope string true The scope of the attribute.

Scope is a string and acts as namespace for the attribute name.
»» description string false Attribute description.
»» value string true The current value of the attribute.

Attribute type is implicit, inferred from the JSON type.

Supported types: number, string, array of numbers, array of strings.
Mixed arrays are not allowed.

Response Headers

Status Header Type Format Description
200 X-Total-Count string Custom header indicating the total number of devices for the given query parameters

List Filters

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/inventory/filters \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v2/inventory/filters HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v2/inventory/filters',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v2/inventory/filters',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v2/inventory/filters', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v2/inventory/filters', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v2/inventory/filters");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v2/inventory/filters", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /filters

List all the saved filters

This operation is only available in our commercial offering and requires you to be on the following plans:

Parameters

Name In Type Required Description
page query number(integer) false Starting page.
per_page query number(integer) false Number of results per page.

Example responses

200 Response

[
  {
    "id": "myfilter",
    "name": "My Filter",
    "terms": [
      {
        "scope": "inventory",
        "attribute": "serial_no",
        "type": "$eq",
        "value": "123456789"
      }
    ]
  }
]

Responses

Status Meaning Description Schema
200 OK Successful response. Inline
400 Bad Request Missing or malformed request parameters. See error for details. Error
500 Internal Server Error Internal error. Error

Response Schema

Status Code 200

ListOfFilters

Name Type Required Restrictions Description
ListOfFilters [Filter] false [Filter definition]
» id string true Unique identifier of the saved filter.
» name string true Name of the saved filter.
» terms [FilterPredicate] false [Attribute filter predicate]
»» scope string true Attribute scope.
»» attribute string true Attribute name.
»» type string true Type or operator of the filter predicate.

»» value string true The value of the attribute to be used in filtering.
Attribute type is implicit, inferred from the JSON type.

The $exists operator expects a boolean value: true means the specified
attribute exists, false means the specified attribute doesn't exist.

The $regex operator expects a string as a Perl compatible regular expression
(PCRE), automatically anchored by ^. If the regular expression is not valid,
the filter will produce no results. If you need to specify options and flags,
you can provide the full regex in the format of /regex/flags, for example
/[a-z]+/i.

Enumerated Values

Property Value
type $eq
type $gt
type $gte
type $in
type $lt
type $lte
type $ne
type $nin
type $exists
type $regex

Response Headers

Status Header Type Format Description
200 Link string Standard header, used for page navigation.

Supported relation types are 'first', 'next' and 'prev'. | |200|X-Total-Count|string||Custom header indicating the total number of saved filters for the given query parameters|

Create Filter

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/inventory/filters \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

POST https://hosted.mender.io/api/management/v2/inventory/filters HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "name": "string",
  "terms": [
    {
      "type": "$eq",
      "attribute": "serial_no",
      "scope": "inventory",
      "value": "123456789"
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v2/inventory/filters',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v2/inventory/filters',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.post('https://hosted.mender.io/api/management/v2/inventory/filters', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v2/inventory/filters', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v2/inventory/filters");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v2/inventory/filters", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /filters

Create a new saved filter from a filter definition

This operation is only available in our commercial offering and requires you to be on the following plans:

Body parameter

{
  "name": "string",
  "terms": [
    {
      "type": "$eq",
      "attribute": "serial_no",
      "scope": "inventory",
      "value": "123456789"
    }
  ]
}

Parameters

Name In Type Required Description
body body object false The definition of the filter
» name body string false Name of the filter, must be unique.
» terms body [FilterPredicate] false List of filter predicates, chained with boolean AND operators to build the search condition definition.
»» scope body string true Attribute scope.
»» attribute body string true Attribute name.
»» type body string true Type or operator of the filter predicate.
»» value body string true The value of the attribute to be used in filtering.

Detailed descriptions

»» type: Type or operator of the filter predicate.

Operator Name Argument type
$eq Equal (==) any
$ne Not equal (!=) any
$gt Greater than (>) any
$gte Greater than or equal (>=) any
$lt Less than (<) any
$lte Less than or equal (<=) any
$exists Attribute exists bool
$in Is an element of array
$nin Is not an element of array
$regex Regex filter string

»» value: The value of the attribute to be used in filtering. Attribute type is implicit, inferred from the JSON type.

The $exists operator expects a boolean value: true means the specified attribute exists, false means the specified attribute doesn't exist.

The $regex operator expects a string as a Perl compatible regular expression (PCRE), automatically anchored by ^. If the regular expression is not valid, the filter will produce no results. If you need to specify options and flags, you can provide the full regex in the format of /regex/flags, for example /[a-z]+/i.

Enumerated Values

Parameter Value
»» type $eq
»» type $gt
»» type $gte
»» type $in
»» type $lt
»» type $lte
»» type $ne
»» type $nin
»» type $exists
»» type $regex

Example responses

400 Response

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
201 Created The filter was successfully created. None
400 Bad Request Missing or malformed request parameters. See error for details. Error
409 Conflict A filter with the same name already exists. Error
500 Internal Server Error Internal error. Error

Response Headers

Status Header Type Format Description
201 Location string URL of the newly created filter.

Show Filter

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/inventory/filters/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v2/inventory/filters/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v2/inventory/filters/{id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v2/inventory/filters/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v2/inventory/filters/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v2/inventory/filters/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v2/inventory/filters/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v2/inventory/filters/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /filters/{id}

Get the definition of a saved filter

This operation is only available in our commercial offering and requires you to be on the following plans:

Parameters

Name In Type Required Description
id path string true Filter identifier.

Example responses

200 Response

{
  "id": "myfilter",
  "name": "My Filter",
  "terms": [
    {
      "scope": "inventory",
      "attribute": "serial_no",
      "type": "$eq",
      "value": "123456789"
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successful response. Filter
404 Not Found The filter was not found. ErrorNotFound
500 Internal Server Error Internal error. Error

Delete Filter

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v2/inventory/filters/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

DELETE https://hosted.mender.io/api/management/v2/inventory/filters/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v2/inventory/filters/{id}',
{
  method: 'DELETE',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.delete 'https://hosted.mender.io/api/management/v2/inventory/filters/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.delete('https://hosted.mender.io/api/management/v2/inventory/filters/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('DELETE','https://hosted.mender.io/api/management/v2/inventory/filters/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v2/inventory/filters/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("DELETE");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "https://hosted.mender.io/api/management/v2/inventory/filters/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /filters/{id}

Delete a saved filter

This operation is only available in our commercial offering and requires you to be on the following plans:

Parameters

Name In Type Required Description
id path string true Filter identifier.

Example responses

400 Response

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content The filter was successfully deleted. None
400 Bad Request Missing or malformed request parameters. See error for details. Error
500 Internal Server Error Internal error. Error

Execute Filter

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/inventory/filters/{id}/search \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v2/inventory/filters/{id}/search HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v2/inventory/filters/{id}/search',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v2/inventory/filters/{id}/search',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v2/inventory/filters/{id}/search', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v2/inventory/filters/{id}/search', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v2/inventory/filters/{id}/search");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v2/inventory/filters/{id}/search", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /filters/{id}/search

Search devices using saved filter

This operation is only available in our commercial offering and requires you to be on the following plans:

Parameters

Name In Type Required Description
id path string true Filter identifier.
page query number(integer) false Starting page.
per_page query number(integer) false Number of results per page.

Example responses

Successful response.

[
  {
    "id": "291ae0e5956c69c2267489213df4459d19ed48a806603def19d417d004a4b67e",
    "attributes": [
      {
        "name": "ip_addr",
        "scope": "inventory",
        "value": "1.2.3.4",
        "description": "IP address"
      },
      {
        "name": "mac_addr",
        "scope": "inventory",
        "value": "00.01:02:03:04:05",
        "description": "MAC address"
      }
    ],
    "updated_ts": "2016-10-03T16:58:51.639Z"
  },
  {
    "id": "76f40e5956c699e327489213df4459d1923e1a806603def19d417d004a4a3ef",
    "attributes": [
      {
        "name": "mac",
        "scope": "inventory",
        "value": "00:01:02:03:04:05",
        "description": "MAC address"
      }
    ],
    "updated_ts": "2016-10-04T18:24:21.432Z"
  }
]

400 Response

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK Successful response. Inline
400 Bad Request Missing or malformed request parameters. Error
404 Not Found The filter was not found. ErrorNotFound
500 Internal Server Error Internal error. Error

Response Schema

Status Code 200

ListOfDevices

Name Type Required Restrictions Description
ListOfDevices [DeviceInventory] false
» id string false Mender-assigned unique ID.
» updated_ts string false Timestamp of the most recent attribute update.
» attributes [Attribute] false A list of attribute descriptors.
»» name string true A human readable, unique attribute ID, e.g. 'device_type', 'ip_addr', 'cpu_load', etc.
»» scope string true The scope of the attribute.

Scope is a string and acts as namespace for the attribute name.
»» description string false Attribute description.
»» value string true The current value of the attribute.

Attribute type is implicit, inferred from the JSON type.

Supported types: number, string, array of numbers, array of strings.
Mixed arrays are not allowed.

Response Headers

Status Header Type Format Description
200 Link string Standard header used for page navigation, page relations: 'first', 'next' and 'prev'.
200 X-Total-Count string Total number of devices matched query.

Schemas

Attribute

{
  "name": "serial_no",
  "scope": "inventory",
  "description": "Serial number",
  "value": "123456789"
}

Attribute descriptor.

Properties

Name Type Required Description
name string true A human readable, unique attribute ID, e.g. 'device_type', 'ip_addr', 'cpu_load', etc.
scope string true The scope of the attribute.

Scope is a string and acts as namespace for the attribute name.
description string false Attribute description.
value string true The current value of the attribute.

Attribute type is implicit, inferred from the JSON type.

Supported types: number, string, array of numbers, array of strings.
Mixed arrays are not allowed.

DeviceInventory

{
  "id": "291ae0e5956c69c2267489213df4459d19ed48a806603def19d417d004a4b67e",
  "attributes": [
    {
      "name": "ip_addr",
      "scope": "inventory",
      "value": "1.2.3.4",
      "description": "IP address"
    },
    {
      "name": "mac_addr",
      "scope": "inventory",
      "value": "00.01:02:03:04:05",
      "description": "MAC address"
    }
  ],
  "updated_ts": "2016-10-03T16:58:51.639Z"
}

Properties

Name Type Required Description
id string false Mender-assigned unique ID.
updated_ts string false Timestamp of the most recent attribute update.
attributes [Attribute] false A list of attribute descriptors.

Error

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Error descriptor.

Properties

Name Type Required Description
error string false Description of the error.
request_id string false Request ID (same as in X-MEN-RequestID header).

ErrorNotFound

{
  "error": "filter not found",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Error descriptor.

Properties

Name Type Required Description
error string false Description of the error.
request_id string false Request ID (same as in X-MEN-RequestID header).

Filter

{
  "id": "myfilter",
  "name": "My Filter",
  "terms": [
    {
      "scope": "inventory",
      "attribute": "serial_no",
      "type": "$eq",
      "value": "123456789"
    }
  ]
}

Filter definition

Properties

Name Type Required Description
id string true Unique identifier of the saved filter.
name string true Name of the saved filter.
terms [FilterPredicate] false [Attribute filter predicate]

FilterPredicate

{
  "type": "$eq",
  "attribute": "serial_no",
  "scope": "inventory",
  "value": "123456789"
}

Attribute filter predicate

Properties

Name Type Required Description
scope string true Attribute scope.
attribute string true Attribute name.
type string true Type or operator of the filter predicate.

value string true The value of the attribute to be used in filtering.
Attribute type is implicit, inferred from the JSON type.

The $exists operator expects a boolean value: true means the specified
attribute exists, false means the specified attribute doesn't exist.

The $regex operator expects a string as a Perl compatible regular expression
(PCRE), automatically anchored by ^. If the regular expression is not valid,
the filter will produce no results. If you need to specify options and flags,
you can provide the full regex in the format of /regex/flags, for example
/[a-z]+/i.

Enumerated Values

Property Value
type $eq
type $gt
type $gte
type $in
type $lt
type $lte
type $ne
type $nin
type $exists
type $regex

SortCriteria

{
  "attribute": "serial_no",
  "scope": "inventory",
  "order": "asc"
}

Sort criteria definition

Properties

Name Type Required Description
scope string true Attribute scope.
attribute string true Attribute name.
order string true Order direction, ascending ("asc") or descending ("desc").

Enumerated Values

Property Value
order asc
order desc

Deployments

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

An API for deployments and artifacts management. Intended for use by the web GUI.

Base URLs:

List Deployments

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deployments/deployments \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/deployments/deployments HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/deployments/deployments',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/deployments/deployments', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/deployments/deployments', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/deployments");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/deployments/deployments", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /deployments

Find all deployments

Returns a filtered collection of deployments in the system, including active and historical. If both 'status' and 'query' are not specified, all devices are listed.

Parameters

Name In Type Required Description
status query string false Deployment status filter.
search query string false Deployment name or description filter.
page query number(integer) false Results page number
per_page query number(integer) false Maximum number of results per page.
created_before query number(integer) false List only deployments created before and equal to Unix timestamp (UTC)
created_after query number(integer) false List only deployments created after and equal to Unix timestamp (UTC)

Enumerated Values

Parameter Value
status inprogress
status finished
status pending
status scheduled

Example responses

Successful response.

[
  {
    "created": "2016-02-11T13:03:17.063493443Z",
    "status": "finished",
    "name": "production",
    "artifact_name": "Application 0.0.1",
    "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
    "finished": "2016-03-11T13:03:17.063493443Z",
    "device_count": 10,
    "retries": 0
  }
]

400 Response

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK Successful response. Inline
400 Bad Request Invalid Request. Error
401 Unauthorized Unauthorized. None
500 Internal Server Error Internal Server Error. Error

Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [Deployment] false
» created string(date-time) true
» name string true
» artifact_name string true
» id string true
» finished string(date-time) false
» status string true
» device_count integer true
» artifacts [string] false
» phases [DeploymentPhase] false
»» id string false Phase identifier.
»» batch_size integer false Percentage of devices to update in the phase.
»» start_ts string(date-time) false Start date of a phase.
May be undefined for the first phase of a deployment.
»» device_count integer false Number of devices which already requested an update within this phase.
» retries integer false The number of times a device can retry the deployment in case of failure, defaults to 0
» max_devices integer false max_devices denotes a limit on a number of completed deployments (failed or successful) above which the dynamic deployment will be finished.
» initial_device_count integer false In case of dynamic deployments this is a number of devices targeted initially (maching the filter at the moment of deployment creation).
» dynamic boolean false Flag indicating if the deployment is dynamic or not.
» filter Filter false Inventory filter assigned to the deployment
»» id string true Unique identifier of the saved filter.
»» name string true Name of the saved filter.
»» terms [FilterPredicate] false [Attribute filter predicate]
»»» scope string true The scope of the attribute.

Scope is a string and acts as namespace for the attribute name.
»»» attribute string true Name of the attribute to be queried for filtering.
»»» type string true Type or operator of the filter predicate.
»»» value string true The value of the attribute to be used in filtering.

Attribute type is implicit, inferred from the JSON type.

Supported types: number, string, array of numbers, array of strings.
Mixed arrays are not allowed.

Enumerated Values

Property Value
status scheduled
status pending
status inprogress
status finished
type $eq
type $gt
type $gte
type $in
type $lt
type $lte
type $ne
type $nin
type $exists

Response Headers

Status Header Type Format Description
200 Link string Standard header, we support 'first', 'next', and 'prev'.

Create Deployment

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/deployments/deployments \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

POST https://hosted.mender.io/api/management/v1/deployments/deployments HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "name": "production",
  "artifact_name": "Application 0.0.1",
  "devices": [
    "00a0c91e6-7dec-11d0-a765-f81d4faebf6"
  ],
  "phases": [
    {
      "batch_size": 5,
      "start_ts": "2020-07-06T15:04:49.114046203+02:00"
    },
    {
      "batch_size": 15,
      "start_ts": "2020-07-06T16:04:49.114046203+02:00"
    },
    {
      "start_ts": "2020-07-06T17:04:49.114046203+02:00"
    }
  ],
  "retries": 3
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v1/deployments/deployments',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.post('https://hosted.mender.io/api/management/v1/deployments/deployments', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v1/deployments/deployments', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/deployments");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v1/deployments/deployments", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /deployments

Create a deployment

Deploy software to specified devices. Artifact is auto assigned to the device from all available artifacts based on artifact name and device type. Devices for which there are no compatible artifacts to be installed are considered finished successfully as well as receive status of noartifact. If there is no artifacts for the deployment, deployment will not be created and the 422 Unprocessable Entity status code will be returned.

Body parameter

{
  "name": "production",
  "artifact_name": "Application 0.0.1",
  "devices": [
    "00a0c91e6-7dec-11d0-a765-f81d4faebf6"
  ],
  "phases": [
    {
      "batch_size": 5,
      "start_ts": "2020-07-06T15:04:49.114046203+02:00"
    },
    {
      "batch_size": 15,
      "start_ts": "2020-07-06T16:04:49.114046203+02:00"
    },
    {
      "start_ts": "2020-07-06T17:04:49.114046203+02:00"
    }
  ],
  "retries": 3
}

Parameters

Name In Type Required Description
body body NewDeployment true New deployment that needs to be created.

Example responses

400 Response

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
201 Created New deployment created. None
400 Bad Request Invalid Request. Error
401 Unauthorized Unauthorized. None
403 Forbidden Feature not available in your Plan. Error
422 Unprocessable Entity Unprocessable Entity. Error
500 Internal Server Error Internal Server Error. Error

Response Headers

Status Header Type Format Description
201 Location string URL of the newly created deployment.

Create Deployment for a Group of Devices

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/deployments/deployments/group/{name} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

POST https://hosted.mender.io/api/management/v1/deployments/deployments/group/{name} HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "name": "production",
  "artifact_name": "Application 0.0.1",
  "phases": [
    {
      "batch_size": 5,
      "start_ts": "2020-07-06T15:04:49.114046203+02:00"
    },
    {
      "batch_size": 15,
      "start_ts": "2020-07-06T16:04:49.114046203+02:00"
    },
    {
      "start_ts": "2020-07-06T17:04:49.114046203+02:00"
    }
  ],
  "retries": 3
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments/group/{name}',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v1/deployments/deployments/group/{name}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.post('https://hosted.mender.io/api/management/v1/deployments/deployments/group/{name}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v1/deployments/deployments/group/{name}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/deployments/group/{name}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v1/deployments/deployments/group/{name}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /deployments/group/{name}

Create a deployment for a group of devices

Deploy software to devices belonging to the specified group.

Artifact is auto assigned to the device from all available artifacts based on artifact name and device type. Devices for which there are no compatible artifacts to be installed are considered finished successfully as well as receive status of noartifact. If there is no artifacts for the deployment, deployment will not be created and the 422 Unprocessable Entity status code will be returned.

Body parameter

{
  "name": "production",
  "artifact_name": "Application 0.0.1",
  "phases": [
    {
      "batch_size": 5,
      "start_ts": "2020-07-06T15:04:49.114046203+02:00"
    },
    {
      "batch_size": 15,
      "start_ts": "2020-07-06T16:04:49.114046203+02:00"
    },
    {
      "start_ts": "2020-07-06T17:04:49.114046203+02:00"
    }
  ],
  "retries": 3
}

Parameters

Name In Type Required Description
name path string true Device group name.
body body NewDeploymentForGroup true New deployment that needs to be created.

Example responses

400 Response

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
201 Created New deployment created. None
400 Bad Request Invalid Request. Error
401 Unauthorized Unauthorized. None
422 Unprocessable Entity Unprocessable Entity. Error
500 Internal Server Error Internal Server Error. Error

Response Headers

Status Header Type Format Description
201 Location string URL of the newly created deployment.

Show Deployment

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deployments/deployments/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/deployments/deployments/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments/{id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/deployments/deployments/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/deployments/deployments/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/deployments/deployments/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/deployments/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/deployments/deployments/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /deployments/{id}

Get the details of a selected deployment

Returns the details of a particular deployment.

Parameters

Name In Type Required Description
id path string true Deployment identifier.

Example responses

200 Response

{
  "created": "2016-02-11T13:03:17.063493443Z",
  "status": "finished",
  "name": "production",
  "artifact_name": "Application 0.0.1",
  "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
  "finished": "2016-03-11T13:03:17.063493443Z",
  "phases": [
    {
      "batch_size": 5
    },
    {
      "start_ts": "2020-07-06T17:04:49.114046203+02:00",
      "device_count": 25
    },
    {
      "batch_size": 15
    },
    {
      "start_ts": "2020-07-06T18:04:49.114046203+02:00",
      "device_count": 10
    },
    {
      "start_ts": "2020-07-06T19:04:49.114046203+02:00",
      "device_count": 0
    }
  ],
  "device_count": 500,
  "retries": 3
}

Responses

Status Meaning Description Schema
200 OK Successful response. Deployment
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

Abort Deployment

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/status \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

PUT https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/status HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "status": "aborted"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/status',
{
  method: 'PUT',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/status',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.put('https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/status', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/status', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/status");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PUT");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/status", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PUT /deployments/{deployment_id}/status

Abort the deployment

Abort an ongoing deployment. For devices included in this deployment it means that:

Body parameter

{
  "status": "aborted"
}

Parameters

Name In Type Required Description
deployment_id path string true Deployment identifier.
body body object true Deployment status.
» status body string true

Enumerated Values

Parameter Value
» status aborted

Example responses

400 Response

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content Status updated successfully. None
400 Bad Request Invalid Request. Error
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
422 Unprocessable Entity Unprocessable Entity. Error
500 Internal Server Error Internal Server Error. Error

Deployment Status Statistics

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/statistics \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/statistics HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/statistics',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/statistics',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/statistics', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/statistics', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/statistics");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/statistics", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /deployments/{deployment_id}/statistics

*Get status count for all devices in a deployment. *

Parameters

Name In Type Required Description
deployment_id path string true Deployment identifier

Example responses

OK

{
  "success": 3,
  "pending": 1,
  "failure": 0,
  "downloading": 1,
  "installing": 2,
  "rebooting": 3,
  "noartifact": 0,
  "already-installed": 0,
  "aborted": 0
}

404 Response

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK OK DeploymentStatistics
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

List Devices in Deployment

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /deployments/{deployment_id}/devices

*Get list of all devices and their respective status for the deployment with the given ID. *

Parameters

Name In Type Required Description
deployment_id path string true Deployment identifier.

Example responses

200 Response

[
  {
    "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
    "finished": "2016-03-11T13:03:17.063493443Z",
    "status": "installing",
    "created": "2016-02-11T13:03:17.063493443Z",
    "device_type": "Raspberry Pi 3",
    "log": false,
    "state": "installing",
    "substate": "installing.enter;script:foo-bar"
  }
]

Responses

Status Meaning Description Schema
200 OK OK Inline
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [Device] false
» id string true Device identifier.
» finished string(date-time) false
» status string true
» created string(date-time) false
» device_type string false
» log boolean true Availability of the device's deployment log.
» state string false State reported by device
» substate string false Additional state information

Enumerated Values

Property Value
status downloading
status installing
status rebooting
status pending
status success
status failure
status noartifact
status already-installed
status aborted
status decommissioned

List Device IDs in Deployment

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deployments/deployments/{id}/device_list \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/deployments/deployments/{id}/device_list HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments/{id}/device_list',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/deployments/deployments/{id}/device_list',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/deployments/deployments/{id}/device_list', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/deployments/deployments/{id}/device_list', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/deployments/{id}/device_list");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/deployments/deployments/{id}/device_list", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /deployments/{id}/device_list

Get the list of device IDs being part of the deployment.

Parameters

Name In Type Required Description
id path string true Deployment identifier.

Example responses

Successful response.

[
  "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
  "00a0c91e6-7dec-11d0-a765-f81d4faebf8",
  "00a0c91e6-7dec-11d0-a765-f81d4faebf7"
]

400 Response

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK Successful response. Inline
400 Bad Request Invalid Request. Error
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

Response Schema

Get Deployment Log for Device

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices/{device_id}/log \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices/{device_id}/log HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices/{device_id}/log',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices/{device_id}/log',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices/{device_id}/log', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices/{device_id}/log', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices/{device_id}/log");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices/{device_id}/log", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /deployments/{deployment_id}/devices/{device_id}/log

Get the log of a selected device's deployment

Parameters

Name In Type Required Description
deployment_id path string true Deployment identifier.
device_id path string true Device identifier.

Example responses

404 Response

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK Successful response. None
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

Remove Device from Deployments

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v1/deployments/deployments/devices/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

DELETE https://hosted.mender.io/api/management/v1/deployments/deployments/devices/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments/devices/{id}',
{
  method: 'DELETE',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.delete 'https://hosted.mender.io/api/management/v1/deployments/deployments/devices/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.delete('https://hosted.mender.io/api/management/v1/deployments/deployments/devices/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('DELETE','https://hosted.mender.io/api/management/v1/deployments/deployments/devices/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/deployments/devices/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("DELETE");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "https://hosted.mender.io/api/management/v1/deployments/deployments/devices/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /deployments/devices/{id}

Remove device from all deployments

Set 'decommissioned' status to all pending device deployments for a given device

Parameters

Name In Type Required Description
id path string true System wide device identifier

Example responses

500 Response

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content Device was removed None
401 Unauthorized Unauthorized. None
500 Internal Server Error Internal server error. Error

List Releases

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deployments/deployments/releases \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/deployments/deployments/releases HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments/releases',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/deployments/deployments/releases',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/deployments/deployments/releases', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/deployments/deployments/releases', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/deployments/releases");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/deployments/deployments/releases", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /deployments/releases

List releases

Returns a collection of releases, allows filtering by release name.

Parameters

Name In Type Required Description
name query string false Release name filter.

Example responses

Successful response.

[
  {
    "name": "my-app-v1.0.1",
    "artifacts": [
      {
        "name": "my-app-v1.0.1",
        "description": "Application v1.0.1",
        "device_types_compatible": [
          "Beagle Bone"
        ],
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "signed": false,
        "modified": "2016-03-11T13:03:17.063493443Z",
        "info": {
          "type_info": {
            "type": "rootfs"
          }
        },
        "files": [
          {
            "name": "rootfs-image-1",
            "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
            "size": 23421351,
            "date": "2016-03-11T13:03:17.063+0000"
          }
        ],
        "metadata": {}
      },
      {
        "name": "my-app-v1.0.1",
        "description": "Application v1.0.1",
        "device_types_compatible": [
          "Raspberry Pi"
        ],
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "signed": false,
        "modified": "2016-03-11T13:03:17.063493443Z",
        "info": {
          "type_info": {
            "type": "rootfs"
          }
        },
        "files": [
          {
            "name": "rootfs-image-1",
            "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
            "size": 23421351,
            "date": "2016-03-11T13:03:17.063+0000"
          }
        ],
        "metadata": {}
      }
    ]
  },
  {
    "name": "my-app-v2.0.0",
    "artifacts": [
      {
        "name": "my-app-v2.0.0",
        "description": "Application v2.0.0",
        "device_types_compatible": [
          "Beagle Bone"
        ],
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "signed": false,
        "modified": "2016-03-11T13:03:17.063493443Z",
        "info": {
          "type_info": {
            "type": "rootfs"
          }
        },
        "files": [
          {
            "name": "rootfs-image-1",
            "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
            "size": 23421351,
            "date": "2016-03-11T13:03:17.063+0000"
          }
        ],
        "metadata": {}
      }
    ]
  }
]

500 Response

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK Successful response. Releases
401 Unauthorized Unauthorized. None
500 Internal Server Error Internal Server Error. Error

List Artifacts

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deployments/artifacts \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/deployments/artifacts HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/artifacts',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/deployments/artifacts',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/deployments/artifacts', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/deployments/artifacts', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/artifacts");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/deployments/artifacts", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /artifacts

List known artifacts

Returns a collection of all artifacts.

Example responses

OK

[
  {
    "name": "Application 1.0.0",
    "description": "Johns Monday test build",
    "device_types_compatible": [
      "Beagle Bone"
    ],
    "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
    "signed": false,
    "modified": "2016-03-11T13:03:17.063493443Z",
    "info": {
      "type_info": {
        "type": "rootfs"
      }
    },
    "files": [
      {
        "name": "rootfs-image-1",
        "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
        "size": 123,
        "date": "2016-03-11T13:03:17.063+0000"
      }
    ],
    "metadata": {}
  }
]

500 Response

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK OK Inline
401 Unauthorized Unauthorized. None
500 Internal Server Error Internal Server Error. Error

Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [Artifact] false [Detailed artifact.]
» name string true
» description string true
» device_types_compatible [string] true
» id string true
» signed boolean false Idicates if artifact is signed or not.
» modified string(date-time) true Represents creation / last edition of any of the artifact properties.
» size number(integer) false Artifact total size in bytes - the size of the actual file that will be transferred to the device (compressed).
» info ArtifactInfo false Information about artifact format and version.
»» format string false
»» version integer false
» updates [Update] false [Single updated to be applied.
]
»» type_info ArtifactTypeInfo false Information about update type.
»»» type string false
»» files [UpdateFile] false [Information about particular update file.
]
»»» name string false
»»» checksum string false
»»» size integer false
»»» date string(date-time) false
»» meta_data object false meta_data is an object of unknown structure as this is dependent of update type (also custom defined by user)

Upload Artifact

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/deployments/artifacts \
  -H 'Content-Type: multipart/form-data' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

POST https://hosted.mender.io/api/management/v1/deployments/artifacts HTTP/1.1
Host: hosted.mender.io
Content-Type: multipart/form-data
Accept: application/json

const inputBody = '{
  "size": 0,
  "description": "string",
  "artifact": "string"
}';
const headers = {
  'Content-Type':'multipart/form-data',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/artifacts',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'multipart/form-data',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v1/deployments/artifacts',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'multipart/form-data',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.post('https://hosted.mender.io/api/management/v1/deployments/artifacts', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'multipart/form-data',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v1/deployments/artifacts', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/artifacts");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"multipart/form-data"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v1/deployments/artifacts", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /artifacts

Upload mender artifact

Upload mender artifact. Multipart request with meta and artifact.

Supports artifact versions v1, v2, 3.

Body parameter

size: 0
description: string
artifact: string

Parameters

Name In Type Required Description
body body object false
» size body integer(long) false Size of the artifact file in bytes.
» description body string false
» artifact body string(binary) true Artifact. It has to be the last part of request.

Detailed descriptions

» size: Size of the artifact file in bytes. DEPRECATED: Size is determined from uploaded content.

Example responses

400 Response

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
201 Created Artifact uploaded. None
400 Bad Request Invalid Request. Error
401 Unauthorized Unauthorized. None
500 Internal Server Error Internal Server Error. Error

Response Headers

Status Header Type Format Description
201 Location string URL of the newly uploaded artifact.

Generate Artifact

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/deployments/artifacts/generate \
  -H 'Content-Type: multipart/form-data' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

POST https://hosted.mender.io/api/management/v1/deployments/artifacts/generate HTTP/1.1
Host: hosted.mender.io
Content-Type: multipart/form-data
Accept: application/json

const inputBody = '{
  "name": "string",
  "description": "string",
  "device_types_compatible": [
    "string"
  ],
  "type": "single_file",
  "args": "string",
  "file": "string"
}';
const headers = {
  'Content-Type':'multipart/form-data',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/artifacts/generate',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'multipart/form-data',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v1/deployments/artifacts/generate',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'multipart/form-data',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.post('https://hosted.mender.io/api/management/v1/deployments/artifacts/generate', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'multipart/form-data',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v1/deployments/artifacts/generate', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/artifacts/generate");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"multipart/form-data"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v1/deployments/artifacts/generate", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /artifacts/generate

Upload raw data to generate a new artifact

Generate a new Mender artifact from raw data and meta data. Multipart request with meta and raw file. Supports generating single-file updates only, using the Single File Update Module (https://hub.mender.io/t/single-file).

Body parameter

name: string
description: string
device_types_compatible:
  - string
type: single_file
args: string
file: string

Parameters

Name In Type Required Description
body body object true
» name body string true Name of the artifact to generate.
» description body string false Description of the artifact to generate.
» device_types_compatible body [string] true An array of compatible device types.
» type body string true Update module used to generate the artifact.
» args body string false Type-specific arguments used to generate the artifact.
» file body string(binary) true Raw file to be used to generate the artifact. It has to be the last part of request.

Enumerated Values

Parameter Value
» type single_file

Example responses

400 Response

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
201 Created Artifact generation request accepted and queued for processing. None
400 Bad Request Invalid Request. Error
401 Unauthorized Unauthorized. None
500 Internal Server Error Internal Server Error. Error

Response Headers

Status Header Type Format Description
201 Location string URL of the artifact going to be generated.

Show Artifact

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deployments/artifacts/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/deployments/artifacts/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /artifacts/{id}

Get the details of a selected artifact

Returns the details of a selected artifact.

Parameters

Name In Type Required Description
id path string true Artifact identifier.

Example responses

Successful response.

{
  "name": "Application 1.0.0",
  "description": "Johns Monday test build",
  "device_types_compatible": [
    "Beagle Bone"
  ],
  "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
  "signed": false,
  "modified": "2016-03-11T13:03:17.063493443Z",
  "info": {
    "type_info": {
      "type": "rootfs"
    }
  },
  "files": [
    {
      "name": "rootfs-image-1",
      "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
      "size": 123,
      "date": "2016-03-11T13:03:17.063+0000"
    }
  ],
  "metadata": {}
}

400 Response

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK Successful response. Artifact
400 Bad Request Invalid Request. Error
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

Update Artifact Info

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v1/deployments/artifacts/{id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

PUT https://hosted.mender.io/api/management/v1/deployments/artifacts/{id} HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "description": "Some description"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}',
{
  method: 'PUT',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.put('https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PUT");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PUT /artifacts/{id}

Update description of a selected artifact

Edit description. Artifact is not allowed to be edited if it was used in any deployment.

Body parameter

{
  "description": "Some description"
}

Parameters

Name In Type Required Description
id path string true Artifact identifier.
body body ArtifactUpdate false

Example responses

400 Response

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content The artifact metadata updated successfully. None
400 Bad Request Invalid Request. Error
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
422 Unprocessable Entity Unprocessable Entity. Error
500 Internal Server Error Internal Server Error. Error

Delete Artifact

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v1/deployments/artifacts/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

DELETE https://hosted.mender.io/api/management/v1/deployments/artifacts/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}',
{
  method: 'DELETE',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.delete 'https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.delete('https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('DELETE','https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("DELETE");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /artifacts/{id}

Delete the artifact

Deletes the artifact from file and artifacts storage. Artifacts used by deployments in progress can not be deleted until deployment finishes.

Parameters

Name In Type Required Description
id path string true Artifact identifier.

Example responses

404 Response

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content The artifact deleted successfully. None
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
409 Conflict Artifact used by active deployment. Error
500 Internal Server Error Internal Server Error. Error

Download Artifact

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}/download \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}/download HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}/download',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}/download',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}/download', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}/download', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}/download");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/deployments/artifacts/{id}/download", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /artifacts/{id}/download

Get the download link of a selected artifact

Generates signed URL for downloading artifact file. URI can be used only with GET HTTP method. Link supports such HTTP headers: 'Range', 'If-Modified-Since', 'If-Unmodified-Since' It is valid for specified period of time.

Parameters

Name In Type Required Description
id path string true Artifact identifier.

Example responses

200 Response

{
  "uri": "http://mender.io/artifact.tar.gz.mender",
  "expire": "2016-10-29T10:45:34Z"
}

Responses

Status Meaning Description Schema
200 OK Successful response. ArtifactLink
400 Bad Request Invalid Request. Error
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

Get Storage Usage

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deployments/limits/storage \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/deployments/limits/storage HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/limits/storage',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/deployments/limits/storage',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/deployments/limits/storage', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/deployments/limits/storage', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/deployments/limits/storage");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/deployments/limits/storage", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /limits/storage

Get storage limit and current storage usage

Get storage limit and current storage usage for currently logged in user. If the limit value is 0 it means there is no limit for storage for logged in user.

Example responses

200 Response

{
  "limit": 1073741824,
  "usage": 536870912
}

Responses

Status Meaning Description Schema
200 OK Successful response. StorageLimit
401 Unauthorized Unauthorized. None
500 Internal Server Error Internal Server Error. Error

Schemas

Error

{
  "error": "failed to decode request body: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Error descriptor.

Properties

Name Type Required Description
error string false Description of the error.
request_id string false Request ID (same as in X-MEN-RequestID header).

NewDeployment

{
  "name": "production",
  "artifact_name": "Application 0.0.1",
  "devices": [
    "00a0c91e6-7dec-11d0-a765-f81d4faebf6"
  ],
  "phases": [
    {
      "batch_size": 5,
      "start_ts": "2020-07-06T15:04:49.114046203+02:00"
    },
    {
      "batch_size": 15,
      "start_ts": "2020-07-06T16:04:49.114046203+02:00"
    },
    {
      "start_ts": "2020-07-06T17:04:49.114046203+02:00"
    }
  ],
  "retries": 3
}

Properties

Name Type Required Description Plans
name string true
artifact_name string true
devices [string] true
phases [NewDeploymentPhase] false professional, enterprise
retries integer false The number of times a device can retry the deployment in case of failure, defaults to 0

NewDeploymentForGroup

{
  "name": "production",
  "artifact_name": "Application 0.0.1",
  "phases": [
    {
      "batch_size": 5,
      "start_ts": "2020-07-06T15:04:49.114046203+02:00"
    },
    {
      "batch_size": 15,
      "start_ts": "2020-07-06T16:04:49.114046203+02:00"
    },
    {
      "start_ts": "2020-07-06T17:04:49.114046203+02:00"
    }
  ],
  "retries": 3
}

Properties

Name Type Required Description
name string true
artifact_name string true

Deployment

{
  "created": "2016-02-11T13:03:17.063493443Z",
  "status": "finished",
  "name": "production",
  "artifact_name": "Application 0.0.1",
  "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
  "finished": "2016-03-11T13:03:17.063493443Z",
  "phases": [
    {
      "batch_size": 5
    },
    {
      "start_ts": "2020-07-06T17:04:49.114046203+02:00",
      "device_count": 25
    },
    {
      "batch_size": 15
    },
    {
      "start_ts": "2020-07-06T18:04:49.114046203+02:00",
      "device_count": 10
    },
    {
      "start_ts": "2020-07-06T19:04:49.114046203+02:00",
      "device_count": 0
    }
  ],
  "device_count": 500,
  "retries": 3
}

Properties

Name Type Required Description
created string(date-time) true
name string true
artifact_name string true
id string true
finished string(date-time) false
status string true
device_count integer true
artifacts [string] false
phases [DeploymentPhase] false
retries integer false The number of times a device can retry the deployment in case of failure, defaults to 0
max_devices integer false max_devices denotes a limit on a number of completed deployments (failed or successful) above which the dynamic deployment will be finished.
initial_device_count integer false In case of dynamic deployments this is a number of devices targeted initially (maching the filter at the moment of deployment creation).
dynamic boolean false Flag indicating if the deployment is dynamic or not.
filter Filter false Inventory filter assigned to the deployment

Enumerated Values

Property Value
status scheduled
status pending
status inprogress
status finished

NewDeploymentPhase

{
  "start_ts": "2019-07-07T21:10:17.063493443Z",
  "batch_size": 5
}

Properties

Name Type Required Description
batch_size integer false Percentage of devices to update in the phase.
This field is optional for the last phase.
The last phase will contain the rest of the devices.
Note that if the percentage of devices entered does not
add up to a whole number of devices it is rounded down,
and in the case it is rounded down to zero, a 400 error
will be returned. This is mostly a concern when the deployment
consists of a low number of devices, like say 5 percent of 11
devices will round to zero, and an error is returned by the server.
start_ts string(date-time) false Start date of a phase.
Can be skipped for the first phase of a new deployment definition ('start immediately').

DeploymentPhase

{
  "application/json": {
    "id": "foo",
    "start_ts": "2020-07-06T15:04:49.114046203+02:00",
    "batch_size": 5,
    "device_count": 42
  }
}

Properties

Name Type Required Description
id string false Phase identifier.
batch_size integer false Percentage of devices to update in the phase.
start_ts string(date-time) false Start date of a phase.
May be undefined for the first phase of a deployment.
device_count integer false Number of devices which already requested an update within this phase.

DeploymentStatistics

{
  "success": 3,
  "pending": 1,
  "failure": 0,
  "downloading": 1,
  "installing": 2,
  "rebooting": 3,
  "noartifact": 0,
  "already-installed": 0,
  "aborted": 0
}

Properties

Name Type Required Description
success integer true Number of successful deployments.
pending integer true Number of pending deployments.
downloading integer true Number of deployments being downloaded.
rebooting integer true Number of deployments devices are rebooting into.
installing integer true Number of deployments devices being installed.
failure integer true Number of failed deployments.
noartifact integer true Do not have appropriate artifact for device type.
already-installed integer true Number of devices unaffected by upgrade, since they are already running the specified software version.
aborted integer true Number of deployments aborted by user.

Device

{
  "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
  "finished": "2016-03-11T13:03:17.063493443Z",
  "status": "installing",
  "created": "2016-02-11T13:03:17.063493443Z",
  "device_type": "Raspberry Pi 3",
  "log": false,
  "state": "installing",
  "substate": "installing.enter;script:foo-bar"
}

Properties

Name Type Required Description
id string true Device identifier.
finished string(date-time) false
status string true
created string(date-time) false
device_type string false
log boolean true Availability of the device's deployment log.
state string false State reported by device
substate string false Additional state information

Enumerated Values

Property Value
status downloading
status installing
status rebooting
status pending
status success
status failure
status noartifact
status already-installed
status aborted
status decommissioned

ArtifactUpdate

{
  "description": "Some description"
}

Artifact information update.

Properties

Name Type Required Description
description string false

ArtifactTypeInfo

{
  "type": "string"
}

Information about update type.

Properties

Name Type Required Description
type string false

UpdateFile

{
  "name": "string",
  "checksum": "string",
  "size": 0,
  "date": "2019-08-24T14:15:22Z"
}

Information about particular update file.

Properties

Name Type Required Description
name string false
checksum string false
size integer false
date string(date-time) false

Update

{
  "type_info": {
    "type": "string"
  },
  "files": [
    {
      "name": "string",
      "checksum": "string",
      "size": 0,
      "date": "2019-08-24T14:15:22Z"
    }
  ],
  "meta_data": {}
}

Single updated to be applied.

Properties

Name Type Required Description
type_info ArtifactTypeInfo false Information about update type.
files [UpdateFile] false [Information about particular update file.
]
meta_data object false meta_data is an object of unknown structure as this is dependent of update type (also custom defined by user)

ArtifactInfo

{
  "format": "string",
  "version": 0
}

Information about artifact format and version.

Properties

Name Type Required Description
format string false
version integer false

Artifact

{
  "name": "Application 1.0.0",
  "size": 36891648,
  "description": "Johns Monday test build",
  "device_types_compatible": [
    "Beagle Bone"
  ],
  "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
  "signed": false,
  "modified": "2016-03-11T13:03:17.063493443Z",
  "info": {
    "type_info": {
      "type": "rootfs"
    }
  },
  "files": [
    {
      "name": "rootfs-image-1",
      "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
      "size": 123,
      "date": "2016-03-11T13:03:17.063+0000"
    }
  ],
  "metadata": {}
}

Detailed artifact.

Properties

Name Type Required Description
name string true
description string true
device_types_compatible [string] true
id string true
signed boolean false Idicates if artifact is signed or not.
modified string(date-time) true Represents creation / last edition of any of the artifact properties.
size number(integer) false Artifact total size in bytes - the size of the actual file that will be transferred to the device (compressed).
info ArtifactInfo false Information about artifact format and version.
updates [Update] false [Single updated to be applied.
]
{
  "uri": "http://mender.io/artifact.tar.gz.mender",
  "expire": "2016-10-29T10:45:34Z"
}

URL for artifact file download.

Name Type Required Description
uri string true
expire string(date-time) true

StorageLimit

{
  "limit": 1073741824,
  "usage": 536870912
}

Tenant account storage limit and storage usage.

Properties

Name Type Required Description
limit integer true Storage limit in bytes. If set to 0 - there is no limit for storage.
usage integer true Current storage usage in bytes.

Releases

[
  {
    "name": "my-app-v1.0.1",
    "artifacts": [
      {
        "name": "my-app-v1.0.1",
        "description": "Application v1.0.1",
        "device_types_compatible": [
          "Beagle Bone"
        ],
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "signed": false,
        "modified": "2016-03-11T13:03:17.063493443Z",
        "info": {
          "type_info": {
            "type": "rootfs"
          }
        },
        "files": [
          {
            "name": "rootfs-image-1",
            "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
            "size": 23421351,
            "date": "2016-03-11T13:03:17.063+0000"
          }
        ],
        "metadata": {}
      },
      {
        "name": "my-app-v1.0.1",
        "description": "Application v1.0.1",
        "device_types_compatible": [
          "Raspberry Pi"
        ],
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "signed": false,
        "modified": "2016-03-11T13:03:17.063493443Z",
        "info": {
          "type_info": {
            "type": "rootfs"
          }
        },
        "files": [
          {
            "name": "rootfs-image-1",
            "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
            "size": 23421351,
            "date": "2016-03-11T13:03:17.063+0000"
          }
        ],
        "metadata": {}
      }
    ]
  }
]

List of releases

Properties

Name Type Required Description
anonymous [Release] false List of releases

Release

{
  "name": "my-app-v1.0.1",
  "artifacts": [
    {
      "name": "my-app-v1.0.1",
      "description": "Application v1.0.1",
      "device_types_compatible": [
        "Beagle Bone"
      ],
      "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
      "signed": false,
      "modified": "2016-03-11T13:03:17.063493443Z",
      "info": {
        "type_info": {
          "type": "rootfs"
        }
      },
      "files": [
        {
          "name": "rootfs-image-1",
          "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
          "size": 23421351,
          "date": "2016-03-11T13:03:17.063+0000"
        }
      ],
      "metadata": {}
    },
    {
      "name": "my-app-v1.0.1",
      "description": "Application v1.0.1",
      "device_types_compatible": [
        "Raspberry Pi"
      ],
      "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
      "signed": false,
      "modified": "2016-03-11T13:03:17.063493443Z",
      "info": {
        "type_info": {
          "type": "rootfs"
        }
      },
      "files": [
        {
          "name": "rootfs-image-1",
          "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
          "size": 23421351,
          "date": "2016-03-11T13:03:17.063+0000"
        }
      ],
      "metadata": {}
    }
  ]
}

Groups artifacts with the same release name into a single resource.

Properties

Name Type Required Description
name string false release name.
artifacts [Artifact] false list of artifacts for this release.

FilterPredicate

{
  "type": "$eq",
  "attribute": "serial_no",
  "scope": "inventory",
  "value": "123456789"
}

Attribute filter predicate

Properties

Name Type Required Description
scope string true The scope of the attribute.

Scope is a string and acts as namespace for the attribute name.
attribute string true Name of the attribute to be queried for filtering.
type string true Type or operator of the filter predicate.
value string true The value of the attribute to be used in filtering.

Attribute type is implicit, inferred from the JSON type.

Supported types: number, string, array of numbers, array of strings.
Mixed arrays are not allowed.

Enumerated Values

Property Value
type $eq
type $gt
type $gte
type $in
type $lt
type $lte
type $ne
type $nin
type $exists

Filter

{
  "id": "myfilter",
  "name": "My Filter",
  "terms": [
    {
      "scope": "inventory",
      "attribute": "serial_no",
      "type": "$eq",
      "value": "123456789"
    }
  ]
}

Inventory filter assigned to the deployment

Properties

Name Type Required Description
id string true Unique identifier of the saved filter.
name string true Name of the saved filter.
terms [FilterPredicate] false [Attribute filter predicate]

Deployments v2

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

Version 2 of the API for deployments management. Intended for use by the web GUI.

Base URLs:

Create Deployment

Code samples

# You can also use wget
curl -X POST https://docker.mender.io/api/management/v2/deployments/deployments \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

POST https://docker.mender.io/api/management/v2/deployments/deployments HTTP/1.1
Host: docker.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "name": "production",
  "artifact_name": "Application 0.0.1",
  "filter_id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
  "phases": [
    {
      "batch_size": 5,
      "start_ts": "2020-07-06T17:04:49.114046203+02:00"
    },
    {
      "batch_size": 15,
      "start_ts": "2020-07-06T18:04:49.114046203+02:00"
    },
    {
      "start_ts": "2020-07-06T19:04:49.114046203+02:00"
    }
  ],
  "retries": 3
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://docker.mender.io/api/management/v2/deployments/deployments',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.post 'https://docker.mender.io/api/management/v2/deployments/deployments',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.post('https://docker.mender.io/api/management/v2/deployments/deployments', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://docker.mender.io/api/management/v2/deployments/deployments', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://docker.mender.io/api/management/v2/deployments/deployments");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://docker.mender.io/api/management/v2/deployments/deployments", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /deployments

Create a deployment

Deploy software to devices matching the given filter. The artifact is auto assigned to the device from all available artifacts based on artifact name and device type. Devices for which there are no compatible artifacts to be installed are considered finished successfully as well as receive the status of noartifact. If there are no artifacts for the deployment, the deployment will not be created and the 422 Unprocessable Entity status code will be returned. Dynamic deployments feature is available only to Enterprise users.

This operation is only available in our commercial offering and requires you to be on the following plans:

Body parameter

{
  "name": "production",
  "artifact_name": "Application 0.0.1",
  "filter_id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
  "phases": [
    {
      "batch_size": 5,
      "start_ts": "2020-07-06T17:04:49.114046203+02:00"
    },
    {
      "batch_size": 15,
      "start_ts": "2020-07-06T18:04:49.114046203+02:00"
    },
    {
      "start_ts": "2020-07-06T19:04:49.114046203+02:00"
    }
  ],
  "retries": 3
}

Parameters

Name In Type Required Description
body body NewDeployment true New deployment that needs to be created.

Example responses

400 Response

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
201 Created New deployment created. None
400 Bad Request Bad request, see error message for details. Error
403 Forbidden Feature not available in your Plan. Error
422 Unprocessable Entity Unprocessable Entity. Error
500 Internal Server Error Internal Server Error. Error

Response Headers

Status Header Type Format Description
201 Location string URL of the newly created deployment.

Schemas

Error

{
  "error": "failed to decode device group data: JSON payload is empty",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Error descriptor.

Properties

Name Type Required Description
error string false Description of the error.
request_id string false Request ID (same as in X-MEN-RequestID header).

NewDeployment

{
  "name": "production",
  "artifact_name": "Application 0.0.1",
  "filter_id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
  "phases": [
    {
      "batch_size": 5,
      "start_ts": "2020-07-06T17:04:49.114046203+02:00"
    },
    {
      "batch_size": 15,
      "start_ts": "2020-07-06T18:04:49.114046203+02:00"
    },
    {
      "start_ts": "2020-07-06T19:04:49.114046203+02:00"
    }
  ],
  "retries": 3
}

Properties

Name Type Required Description
name string true
artifact_name string true
filter_id string true ID of a filter from inventory service.
phases [NewDeploymentPhase] false
retries integer false The number of times a device can retry the deployment in case of failure, defaults to 0
max_devices integer false max_devices denotes a limit on a number of completed deployments (failed or successful) above which the dynamic deployment will be finished

NewDeploymentPhase

{
  "start_ts": "2019-07-07T21:10:17.063493443Z",
  "batch_size": 5
}

Properties

Name Type Required Description
batch_size integer false Percentage of devices to update in the phase.
This field is optional for the last phase.
The last phase will contain the rest of the devices.
Note that if the percentage of devices entered does not add up to a whole number of devices it is rounded down, and in the case it is rounded down to zero, a 400 error will be returned.
This is mostly a concern when the deployment consists of a low number of devices, like say 5 percent of 11 devices will round to zero, and an error is returned by the server.
In the case of dynamic deployment, the number of devices for each phase is being calculated based on the initial number of devices matching the filter.
start_ts string(date-time) false Start date of a phase.
Can be skipped for the first phase of a new deployment definition ('start immediately').

User administration and authentication

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

An API for user administration and user authentication handling. Intended for use by the web GUI. All responses from the API will contain 'X-MEN-RequestID' header with server-side generated request ID.

Base URLs:

Login

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/useradm/auth/login \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/jwt'

POST https://hosted.mender.io/api/management/v1/useradm/auth/login HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/jwt

const inputBody = '{
  "token2fa": "012234"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/jwt'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/auth/login',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/jwt'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v1/useradm/auth/login',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/jwt'
}

r = requests.post('https://hosted.mender.io/api/management/v1/useradm/auth/login', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/jwt',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v1/useradm/auth/login', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/useradm/auth/login");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/jwt"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v1/useradm/auth/login", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /auth/login

Log in to Mender

Accepts user credentials via standard Basic Auth, and returns a JWT token to be used for authentication in subsequent requests.

Body parameter

{
  "token2fa": "012234"
}

Parameters

Name In Type Required Description
body body Twofactor false Two factor authentication token, required if two factor authentication is

Detailed descriptions

body: Two factor authentication token, required if two factor authentication is enabled and tenant's plan is Professional or Enterprise.

Example responses

200 Response

"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NzYxMTkxMzYsImlzcyI6Ik1lbmRlciIsInN1YiI6Ijg1NGIzMTA5LTQ4NjItNGEyNS1hMWZiLWYxMTE2MWNlN2E4NCIsInNjcCI6WyJtZW5kZXIuKiJdfQ.X7Ief4PhPLlR6mA2wh3G3K0Z2tud0rK1QJesxu52NfICSeARmlujczs-_1YZxMwI0s-HgpXHbXIjaSVK80BjxjAM1rqpRGvgqSqG-dU5KmglDpAaTr4VaJci3VFPlVUVTRpI7bfqNMnKZtjmOUAGwjvroDUwX1RwayEmms-efGI"

Responses

Status Meaning Description Schema
200 OK Authentication successful - a new JWT is issued and returned.

The JWT is signed with the API's private key ('RS256' signing algorithm), and contains the following standard claims:

Initiate Password Reset Request

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/useradm/auth/password-reset/start \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST https://hosted.mender.io/api/management/v1/useradm/auth/password-reset/start HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "email": "user@mender.io"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/auth/password-reset/start',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v1/useradm/auth/password-reset/start',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.post('https://hosted.mender.io/api/management/v1/useradm/auth/password-reset/start', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v1/useradm/auth/password-reset/start', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/useradm/auth/password-reset/start");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v1/useradm/auth/password-reset/start", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /auth/password-reset/start

Initiate a Password Reset request based on the provided email address

Starts a Password Reset request, sending an email to the user containing a unique, time-based hash which can be used to reset the password of the user.

Body parameter

{
  "email": "user@mender.io"
}

Parameters

Name In Type Required Description
body body PasswordResetRequest false Password Reset request, it includes the email address of the user.

Detailed descriptions

body: Password Reset request, it includes the email address of the user.

Example responses

400 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
202 Accepted The request has been accepted. None
400 Bad Request The request body is malformed. Error
500 Internal Server Error Internal server error. Error

Complete Password Reset Request

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/useradm/auth/password-reset/complete \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST https://hosted.mender.io/api/management/v1/useradm/auth/password-reset/complete HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "secret": "16fd2706-8baf-433b-82eb-8c7fada847da",
  "password": "new password"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/auth/password-reset/complete',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v1/useradm/auth/password-reset/complete',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.post('https://hosted.mender.io/api/management/v1/useradm/auth/password-reset/complete', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v1/useradm/auth/password-reset/complete', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/useradm/auth/password-reset/complete");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v1/useradm/auth/password-reset/complete", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /auth/password-reset/complete

Complete a Password Reset request

Complete a Password Reset request initiated by the /auth/password-reset/start end-point. Caller provides the secret hash received by email, and the new password of the user.

Body parameter

{
  "secret": "16fd2706-8baf-433b-82eb-8c7fada847da",
  "password": "new password"
}

Parameters

Name In Type Required Description
body body PasswordResetCompletion false Password Reset request, it includes the secret hash received by email, as well as the new password of the user.

Detailed descriptions

body: Password Reset request, it includes the secret hash received by email, as well as the new password of the user.

Example responses

400 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
202 Accepted The request has been accepted. None
400 Bad Request The request body is malformed. Error
500 Internal Server Error Internal server error. Error

List Users

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/useradm/users \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/useradm/users HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/users',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/useradm/users',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/useradm/users', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/useradm/users', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/useradm/users");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/useradm/users", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /users

*List all users registered under the tenant owning the JWT. *

Example responses

200 Response

[
  {
    "email": "user@acme.com",
    "id": "806603def19d417d004a4b67e",
    "created_ts": "2020-07-06T15:04:49.114046203+02:00",
    "updated_ts": "2020-07-07T01:04:49.114046203+02:00"
  }
]

Responses

Status Meaning Description Schema
200 OK Successful response. Inline
401 Unauthorized The user cannot be granted authentication. Error
500 Internal Server Error Internal server error. Error

Response Schema

Status Code 200

ListOfUsers

Name Type Required Restrictions Description
ListOfUsers [User] false [User descriptor.]
» email string true A unique email address.
» id string true User Id.
» created_ts string(date-time) false Server-side timestamp of the user creation.
» updated_ts string(date-time) false Server-side timestamp of the last user information update.

Create User

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/useradm/users \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

POST https://hosted.mender.io/api/management/v1/useradm/users HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "email": "user@acme.com",
  "password": "mypass1234",
  "login": {
    "google": "bob@gmail.com"
  }
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/users',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v1/useradm/users',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.post('https://hosted.mender.io/api/management/v1/useradm/users', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v1/useradm/users', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/useradm/users");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v1/useradm/users", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /users

*Create a new user under the tenant owning the JWT. *

Body parameter

{
  "email": "user@acme.com",
  "password": "mypass1234",
  "login": {
    "google": "bob@gmail.com"
  }
}

Parameters

Name In Type Required Description
body body UserNew true New user data.

Example responses

400 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
201 Created The user was successfully created. None
400 Bad Request The request body is malformed. Error
401 Unauthorized The user cannot be granted authentication. Error
422 Unprocessable Entity The email address is duplicated or password is too short. Error
500 Internal Server Error Internal server error. Error

Response Headers

Status Header Type Format Description
201 Location string URI for the newly created 'User' resource.

Show User

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/useradm/users/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/useradm/users/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/users/{id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/useradm/users/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/useradm/users/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/useradm/users/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/useradm/users/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/useradm/users/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /users/{id}

Get user information

Parameters

Name In Type Required Description
id path string true User id.

Example responses

200 Response

{
  "email": "user@acme.com",
  "id": "806603def19d417d004a4b67e",
  "created_ts": "2020-07-06T15:04:49.114046203+02:00",
  "updated_ts": "2020-07-07T01:04:49.114046203+02:00"
}

Responses

Status Meaning Description Schema
200 OK Successful response - a user information is returned. User
401 Unauthorized The user cannot be granted authentication. Error
404 Not Found The user was not found. Error
500 Internal Server Error Internal server error. Error

Update User

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v1/useradm/users/{id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

PUT https://hosted.mender.io/api/management/v1/useradm/users/{id} HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "email": "new_email@acme.com",
  "roles": [
    "RBAC_ROLE_DEPLOY_GROUP_TESTING_DEVICES",
    "RBAC_ROLE_READ_ONLY"
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/users/{id}',
{
  method: 'PUT',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v1/useradm/users/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.put('https://hosted.mender.io/api/management/v1/useradm/users/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/management/v1/useradm/users/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/useradm/users/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PUT");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "https://hosted.mender.io/api/management/v1/useradm/users/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PUT /users/{id}

Update user information

Body parameter

{
  "email": "new_email@acme.com",
  "roles": [
    "RBAC_ROLE_DEPLOY_GROUP_TESTING_DEVICES",
    "RBAC_ROLE_READ_ONLY"
  ]
}

Parameters

Name In Type Required Description
id path string true User id.
body body UserUpdate true Updated user data.

Example responses

400 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content User information updated. None
400 Bad Request The request body is malformed. Error
401 Unauthorized The user cannot be granted authentication. Error
404 Not Found The user does not exist. Error
422 Unprocessable Entity The email address is duplicated or password is too short. Error
500 Internal Server Error Internal server error. Error

Remove User

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v1/useradm/users/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

DELETE https://hosted.mender.io/api/management/v1/useradm/users/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/users/{id}',
{
  method: 'DELETE',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.delete 'https://hosted.mender.io/api/management/v1/useradm/users/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.delete('https://hosted.mender.io/api/management/v1/useradm/users/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('DELETE','https://hosted.mender.io/api/management/v1/useradm/users/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/useradm/users/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("DELETE");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "https://hosted.mender.io/api/management/v1/useradm/users/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /users/{id}

Remove user from the system

Parameters

Name In Type Required Description
id path string true User id.

Example responses

401 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content User removed. None
401 Unauthorized The user cannot be granted authentication. Error
500 Internal Server Error Internal server error. Error

List Roles

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/useradm/roles \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/useradm/roles HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/roles',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/useradm/roles',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/useradm/roles', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/useradm/roles', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/useradm/roles");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/useradm/roles", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /roles

List existing roles

This operation is only available in our commercial offering and requires you to be on the following plans:

Example responses

200 Response

[
  {
    "name": "RBAC_ROLE_NAME",
    "description": "Description of the role",
    "permissions": [
      {
        "action": "http",
        "object": {
          "type": "GET",
          "value": "/api/v1/endpoint"
        }
      },
      {
        "action": "http",
        "object": {
          "type": "POST",
          "value": "/api/v1/endpoint"
        }
      }
    ]
  }
]

Responses

Status Meaning Description Schema
200 OK Successful response. Inline
401 Unauthorized The user cannot be granted authentication. Error
500 Internal Server Error Internal server error. Error

Response Schema

Status Code 200

ListOfRoles

Name Type Required Restrictions Description
ListOfRoles [Role] false [Role descriptor.]
» name string true A unique name.
» description string false Description of the role, as shown in the UI.
» permissions [RolePermission] false [Role permission]
»» action string true Action
»» object RolePermissionObject true Role permission object
»»» type string true Type
»»» value string true Value

Enumerated Values

Property Value
action any
action http
action CREATE_DEPLOYMENT

Create Role

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/useradm/roles \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

POST https://hosted.mender.io/api/management/v1/useradm/roles HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "name": "RBAC_ROLE_NAME",
  "description": "Description of the role",
  "permissions": [
    {
      "action": "http",
      "object": {
        "type": "GET",
        "value": "/api/v1/endpoint"
      }
    },
    {
      "action": "http",
      "object": {
        "type": "POST",
        "value": "/api/v1/endpoint"
      }
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/roles',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v1/useradm/roles',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.post('https://hosted.mender.io/api/management/v1/useradm/roles', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v1/useradm/roles', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/useradm/roles");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v1/useradm/roles", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /roles

Create role

This operation is only available in our commercial offering and requires you to be on the following plans:

Body parameter

{
  "name": "RBAC_ROLE_NAME",
  "description": "Description of the role",
  "permissions": [
    {
      "action": "http",
      "object": {
        "type": "GET",
        "value": "/api/v1/endpoint"
      }
    },
    {
      "action": "http",
      "object": {
        "type": "POST",
        "value": "/api/v1/endpoint"
      }
    }
  ]
}

Parameters

Name In Type Required Description
body body Role true New role data.

Example responses

400 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
201 Created The role was successfully created. None
400 Bad Request The request body is malformed. Error
401 Unauthorized The user cannot be granted authentication. Error
500 Internal Server Error Internal server error. Error

Response Headers

Status Header Type Format Description
201 Location string URI for the newly created 'Role' resource.

Show Role

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/useradm/roles/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/useradm/roles/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/roles/{id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/useradm/roles/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/useradm/roles/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/useradm/roles/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/useradm/roles/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/useradm/roles/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /roles/{id}

Get role information

Returns role information.

This operation is only available in our commercial offering and requires you to be on the following plans:

Parameters

Name In Type Required Description
id path string true Role id.

Example responses

200 Response

{
  "name": "RBAC_ROLE_NAME",
  "description": "Description of the role",
  "permissions": [
    {
      "action": "http",
      "object": {
        "type": "GET",
        "value": "/api/v1/endpoint"
      }
    },
    {
      "action": "http",
      "object": {
        "type": "POST",
        "value": "/api/v1/endpoint"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successful response - a role information is returned. Role
401 Unauthorized The user cannot be granted authentication. Error
404 Not Found The role was not found. Error
500 Internal Server Error Internal server error. Error

Update Role

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v1/useradm/roles/{id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

PUT https://hosted.mender.io/api/management/v1/useradm/roles/{id} HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "name": "RBAC_ROLE_NAME",
  "description": "Description of the role",
  "permissions": [
    {
      "action": "http",
      "object": {
        "type": "GET",
        "value": "/api/v1/endpoint"
      }
    },
    {
      "action": "http",
      "object": {
        "type": "POST",
        "value": "/api/v1/endpoint"
      }
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/roles/{id}',
{
  method: 'PUT',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v1/useradm/roles/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.put('https://hosted.mender.io/api/management/v1/useradm/roles/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/management/v1/useradm/roles/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/useradm/roles/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PUT");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "https://hosted.mender.io/api/management/v1/useradm/roles/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PUT /roles/{id}

Update role description and list of permissions.

This operation is only available in our commercial offering and requires you to be on the following plans:

Body parameter

{
  "name": "RBAC_ROLE_NAME",
  "description": "Description of the role",
  "permissions": [
    {
      "action": "http",
      "object": {
        "type": "GET",
        "value": "/api/v1/endpoint"
      }
    },
    {
      "action": "http",
      "object": {
        "type": "POST",
        "value": "/api/v1/endpoint"
      }
    }
  ]
}

Parameters

Name In Type Required Description
id path string true Role id.
body body Role true Updated role data.

Example responses

400 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
202 Accepted Role information updated. None
400 Bad Request The request body is malformed. Error
401 Unauthorized The user cannot be granted authentication. Error
404 Not Found The role does not exist. Error
500 Internal Server Error Internal server error. Error

Delete Role

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v1/useradm/roles/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

DELETE https://hosted.mender.io/api/management/v1/useradm/roles/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/roles/{id}',
{
  method: 'DELETE',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.delete 'https://hosted.mender.io/api/management/v1/useradm/roles/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.delete('https://hosted.mender.io/api/management/v1/useradm/roles/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('DELETE','https://hosted.mender.io/api/management/v1/useradm/roles/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/useradm/roles/{id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("DELETE");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "https://hosted.mender.io/api/management/v1/useradm/roles/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /roles/{id}

Remove role from the system

This operation is only available in our commercial offering and requires you to be on the following plans:

Parameters

Name In Type Required Description
id path string true Role id.

Example responses

401 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content Role removed. None
401 Unauthorized The user cannot be granted authentication. Error
500 Internal Server Error Internal server error. Error

Show User Settings

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/useradm/settings \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

GET https://hosted.mender.io/api/management/v1/useradm/settings HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/settings',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/useradm/settings',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.get('https://hosted.mender.io/api/management/v1/useradm/settings', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/useradm/settings', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/useradm/settings");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/useradm/settings", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /settings

Get user settings

Example responses

200 Response

{
  "2fa": "enabled"
}

Responses

Status Meaning Description Schema
200 OK Successful response - a user information is returned. Settings
401 Unauthorized The user cannot be granted authentication. Error
500 Internal Server Error Internal server error. Error

Update User Settings

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/useradm/settings \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: API_KEY'

POST https://hosted.mender.io/api/management/v1/useradm/settings HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "2fa": "enabled"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'API_KEY'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/settings',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'API_KEY'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v1/useradm/settings',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'API_KEY'
}

r = requests.post('https://hosted.mender.io/api/management/v1/useradm/settings', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v1/useradm/settings', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/useradm/settings");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v1/useradm/settings", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /settings

Create new or update existing user settings

Body parameter

{
  "2fa": "enabled"
}

Parameters

Name In Type Required Description
body body Settings true New user settings.

Example responses

400 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
201 Created User settings set. None
400 Bad Request The request body is malformed. Error
401 Unauthorized The user cannot be granted authentication. Error
500 Internal Server Error Internal server error. Error

Get 2FA QR code

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/useradm/2faqr \
  -H 'Accept: application/json'

GET https://hosted.mender.io/api/management/v1/useradm/2faqr HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/2faqr',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/useradm/2faqr',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('https://hosted.mender.io/api/management/v1/useradm/2faqr', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/useradm/2faqr', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/useradm/2faqr");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v1/useradm/2faqr", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /2faqr

Get 2FA QR code

Example responses

200 Response

{
  "qr": "string"
}

Responses

Status Meaning Description Schema
200 OK Successful response - a user information is returned. Inline
401 Unauthorized The user cannot be granted authentication. Error
500 Internal Server Error Internal server error. Error

Response Schema

Status Code 200

Name Type Required Restrictions Description
» qr string false The content of the QR code.

Verify the 2FA token

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v1/useradm/2faverify \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

PUT https://hosted.mender.io/api/management/v1/useradm/2faverify HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "token2fa": "string"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/2faverify',
{
  method: 'PUT',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v1/useradm/2faverify',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.put('https://hosted.mender.io/api/management/v1/useradm/2faverify', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/management/v1/useradm/2faverify', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://hosted.mender.io/api/management/v1/useradm/2faverify");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PUT");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "https://hosted.mender.io/api/management/v1/useradm/2faverify", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PUT /2faverify

Verify the 2FA token

Body parameter

{
  "token2fa": "string"
}

Parameters

Name In Type Required Description
body body object true The token
» token2fa body string false The 2FA token to verify.

Example responses

400 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
202 Accepted Successful response - the verification was successful. None
400 Bad Request The request is not valid. Error
401 Unauthorized The verification failed. Error
500 Internal Server Error Internal server error. Error

Schemas

UserNew

{
  "email": "user@acme.com",
  "password": "mypass1234",
  "login": {
    "google": "bob@gmail.com"
  }
}

New user descriptor.

Properties

Name Type Required Description
email string true A unique email address. Non-ascii characters are invalid.
password string false Password.
login object false Alternative login schemes

UserUpdate

{
  "email": "new_email@acme.com",
  "roles": [
    "RBAC_ROLE_DEPLOY_GROUP_TESTING_DEVICES",
    "RBAC_ROLE_READ_ONLY"
  ]
}

Update user information.

Properties

Name Type Required Description
email string false A unique email address.
password string false Password.
roles [string] false List of roles for the user. If not provided existing roles are kept.
» ListOfRoles string false Role name

User

{
  "email": "user@acme.com",
  "id": "806603def19d417d004a4b67e",
  "created_ts": "2020-07-06T15:04:49.114046203+02:00",
  "updated_ts": "2020-07-07T01:04:49.114046203+02:00"
}

User descriptor.

Properties

Name Type Required Description
email string true A unique email address.
id string true User Id.
created_ts string(date-time) false Server-side timestamp of the user creation.
updated_ts string(date-time) false Server-side timestamp of the last user information update.

Role

{
  "name": "RBAC_ROLE_NAME",
  "description": "Description of the role",
  "permissions": [
    {
      "action": "http",
      "object": {
        "type": "GET",
        "value": "/api/v1/endpoint"
      }
    },
    {
      "action": "http",
      "object": {
        "type": "POST",
        "value": "/api/v1/endpoint"
      }
    }
  ]
}

Role descriptor.

Properties

Name Type Required Description
name string true A unique name.
description string false Description of the role, as shown in the UI.
permissions [RolePermission] false [Role permission]

RolePermission

{
  "action": "http",
  "object": {
    "type": "GET",
    "value": ".*"
  }
}

Role permission

Properties

Name Type Required Description
action string true Action
object RolePermissionObject true Role permission object

Enumerated Values

Property Value
action any
action http
action CREATE_DEPLOYMENT

RolePermissionObject

{
  "type": "POST",
  "value": "/api/v1/endpoint"
}

Role permission object

Properties

Name Type Required Description
type string true Type
value string true Value

Error

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Error descriptor.

Properties

Name Type Required Description
error string false Description of the error.
request_id string false Request ID (same as in X-MEN-RequestID header).

Settings

{
  "2fa": "enabled"
}

User settings.

Properties

|2fa|string|false|Enable/disable two-factor authentication for this user.|professional, enterprise|

Enumerated Values

Property Value
2fa enabled
2fa disabled

Twofactor

{
  "token2fa": "012234"
}

Two factor authentication token

Properties

Name Type Required Description
token2fa string true Two factor authentication token

PasswordResetRequest

{
  "email": "user@mender.io"
}

Password reset request

Properties

Name Type Required Description
email string true User's email address

PasswordResetCompletion

{
  "secret": "16fd2706-8baf-433b-82eb-8c7fada847da",
  "password": "new password"
}

Password reset completion

Properties

Name Type Required Description
secret string true Secret hash received by email by the user
password string true New password of the user