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.

Internal APIs

Internal APIs are used by Mender's backend services to communicate with each other. They can also be used to integrate third party systems with the backend when installing Mender on-premise. Note: the API gateway does not expose these endpoints; they are not available for direct consumption by clients on hosted Mender.

Authentication

The end-points that require authentication expect an Authorization header containing a valid JWT token. The format of the Header is:

Authorization: Bearer {access-token}

Replace {access-token} with a valid JWT token. For management APIs, you can obtain a JWT token calling the Login end-point. for device APIs, you can obtain a JWT token calling the Authenticate device end-point.

Personal Access Tokens

The JWT tokens returned by the log-in end-points mentioned above last one week. Therefore, storing and reusing them, for example, from a CI/CD pipeline or a scheduled job is not practical. Personal Access Tokens are long-lived JWT tokens that you can use to programmatically access the Mender management APIs without logging in each time you need to perform API calls or handle the JWT token expiration every week. Personal Access Tokens act as API keys from your CI/CD pipelines or scheduled jobs to access the Mender management APIs. In the documentation, you can read more about Personal Access Tokens.

Common HTTP response codes

The end-point-specific documentation of the Mender API doesn't include the HTTP response codes we consider common responses. The list of common HTTP response codes follows:

HTTP response code Description
401 Unauthorized: the request is missing the Authorization header or its content is not valid
403 Forbidden: the request is forbidden for the current user or device by the Role-based Access Control (RBAC) settings
429 Too Many Requests: the client is flooding the server with too many requests and is required to slow down
500 Internal Server Error: the backend failed to process the request because of an unexpected server-side error

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

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:

List Artifacts

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/devices/v1/deployments/artifacts?release_name=string&device_type=string \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/devices/v1/deployments/artifacts?release_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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/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/devices/v1/deployments/artifacts?release_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{"Bearer {access-token}"},
    }

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

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

GET /artifacts

List artifacts filtering by release name and device type

Returns a collection of up to 100 artifacts matching the provided release name and device type.

Parameters

Name In Type Required Description
release_name query string true name of the release
device_type query string true Device type of device

Example responses

Successful response.

[
  {
    "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
    "name": "Application 1.0.0",
    "description": "Johns Monday test build",
    "device_types_compatible": [
      "Beagle Bone"
    ],
    "info": {
      "format": "mender",
      "version": 3
    },
    "signed": false,
    "updates": [
      {
        "type_info": {
          "type": "rootfs-image"
        },
        "files": [
          {
            "name": "rootfs-image-1",
            "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
            "size": 123,
            "date": "2016-03-11T13:03:17.063+0000"
          }
        ],
        "meta_data": {}
      }
    ],
    "artifact_provides": {
      "artifact_name": "test",
      "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
      "rootfs-image.version": "test"
    },
    "artifact_depends": {
      "device_type": [
        "test"
      ]
    },
    "clears_artifact_provides": [
      "rootfs-image.*"
    ],
    "size": 36891648,
    "modified": "2016-03-11T13:03:17.063493443Z"
  }
]

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. Artifacts
400 Bad Request Invalid Request. Error
401 Unauthorized Unauthorized. Error
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

Show Artifact

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/devices/v1/deployments/artifacts/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/devices/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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/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/devices/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{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/devices/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.

{
  "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
  "name": "Application 1.0.0",
  "description": "Johns Monday test build",
  "device_types_compatible": [
    "Beagle Bone"
  ],
  "info": {
    "format": "mender",
    "version": 3
  },
  "signed": false,
  "updates": [
    {
      "type_info": {
        "type": "rootfs-image"
      },
      "files": [
        {
          "name": "rootfs-image-1",
          "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
          "size": 123,
          "date": "2016-03-11T13:03:17.063+0000"
        }
      ],
      "meta_data": {}
    }
  ],
  "artifact_provides": {
    "artifact_name": "test",
    "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
    "rootfs-image.version": "test"
  },
  "artifact_depends": {
    "device_type": [
      "test"
    ]
  },
  "clears_artifact_provides": [
    "rootfs-image.*"
  ],
  "size": 36891648,
  "modified": "2016-03-11T13:03:17.063493443Z"
}

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. Artifact
400 Bad Request Invalid Request. Error
401 Unauthorized Unauthorized. Error
404 Not Found Not Found. 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/devices/v1/deployments/artifacts/{id}/download \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/devices/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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/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/devices/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{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/devices/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. Error
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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.myupdatebucket.com/image123",
      "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
401 Unauthorized Unauthorized. Error
404 Not Found Not Found. Error
409 Conflict Conflicting request data provided. 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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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
409 Conflict Conflicting request data provided. 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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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
401 Unauthorized Unauthorized. 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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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
401 Unauthorized Unauthorized. Error
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

Fetch Configuration

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/devices/v1/deployments/download/configuration/{deployment_id}/{device_type}/{device_id}?x%2Dmen%2Dexpire=2019-08-24T14%3A15%3A22Z&x%2Dmen%2Dsignature=string \
  -H 'Accept: application/json'

GET https://hosted.mender.io/api/devices/v1/deployments/download/configuration/{deployment_id}/{device_type}/{device_id}?x%2Dmen%2Dexpire=2019-08-24T14%3A15%3A22Z&x%2Dmen%2Dsignature=string HTTP/1.1
Host: hosted.mender.io
Accept: application/json


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

fetch('https://hosted.mender.io/api/devices/v1/deployments/download/configuration/{deployment_id}/{device_type}/{device_id}?x%2Dmen%2Dexpire=2019-08-24T14%3A15%3A22Z&x%2Dmen%2Dsignature=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'
}

result = RestClient.get 'https://hosted.mender.io/api/devices/v1/deployments/download/configuration/{deployment_id}/{device_type}/{device_id}',
  params: {
  'x-men-expire' => 'string(date-time)',
'x-men-signature' => 'string'
}, headers: headers

p JSON.parse(result)

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

r = requests.get('https://hosted.mender.io/api/devices/v1/deployments/download/configuration/{deployment_id}/{device_type}/{device_id}', params={
  'x-men-expire': '2019-08-24T14:15:22Z',  'x-men-signature': 'string'
}, 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/devices/v1/deployments/download/configuration/{deployment_id}/{device_type}/{device_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/devices/v1/deployments/download/configuration/{deployment_id}/{device_type}/{device_id}?x%2Dmen%2Dexpire=2019-08-24T14%3A15%3A22Z&x%2Dmen%2Dsignature=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"},
    }

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

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

GET /download/configuration/{deployment_id}/{device_type}/{device_id}

*Internally generated download link for deploying device configurations. All parameters are generated internally when fetching a configuration deployment. *

Parameters

Name In Type Required Description
deployment_id path string true Deployment UUID
device_type path string true Device type of the calling device
device_id path string true Device UUID
x-men-expire query string(date-time) true Time of link expire
x-men-signature query string true Signature of the URL link
tenant_id query string false Device tenant ID

Example responses

200 Response

"string"

Responses

Status Meaning Description Schema
200 OK Successful response string
400 Bad Request Invalid Request. Error
401 Unauthorized Unauthorized. Error
403 Forbidden The download link has expired or the signature is invalid. None
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).

Artifacts

[
  {}
]

Properties

None

Artifact

{
  "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
  "name": "Application 1.0.0",
  "description": "Johns Monday test build",
  "device_types_compatible": [
    "Beagle Bone"
  ],
  "info": {
    "format": "mender",
    "version": 3
  },
  "signed": false,
  "updates": [
    {
      "type_info": {
        "type": "rootfs-image"
      },
      "files": [
        {
          "name": "rootfs-image-1",
          "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
          "size": 123,
          "date": "2016-03-11T13:03:17.063+0000"
        }
      ],
      "meta_data": {}
    }
  ],
  "artifact_provides": {
    "artifact_name": "test",
    "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
    "rootfs-image.version": "test"
  },
  "artifact_depends": {
    "device_type": [
      "test"
    ]
  },
  "clears_artifact_provides": [
    "rootfs-image.*"
  ],
  "size": 36891648,
  "modified": "2016-03-11T13:03:17.063493443Z"
}

Detailed artifact.

Properties
Name Type Required Description
id string true
name string true
description string false
device_types_compatible [string] true An array of compatible device types.
info ArtifactInfo false Information about artifact format and version.
signed boolean false Idicates if artifact is signed or not.
updates [Update] false [Single updated to be applied.
]
artifact_provides object false List of Artifact provides.

Map of key/value pairs, where both keys and values are strings.
» additionalProperties string false
artifact_depends object false List of Artifact depends.

Map of key/value pairs, where keys are strings and values are lists of strings.
» additionalProperties [string] false
clears_artifact_provides [string] false List of Clear Artifact provides.
size number(integer) false Artifact total size in bytes - the size of the actual file that will be transferred to the device (compressed).
modified string(date-time) true Represents creation / last edition of any of the artifact properties.

ArtifactInfo

{
  "format": "string",
  "version": 0
}

Information about artifact format and version.

Properties
Name Type Required Description
format string false
version integer false
{
  "uri": "http://mender.io/artifact.tar.gz.mender",
  "expire": "2016-10-29T10:45:34Z"
}

URL for artifact file download.

Properties
Name Type Required Description
uri string true
expire string(date-time) true

ArtifactTypeInfo

{
  "type": "string"
}

Information about update type.

Properties
Name Type Required Description
type string false Note that for emtpy Artifacts, the type is 'null'

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)

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

DeploymentStatus

{
  "status": "success"
}

Properties
Name Type Required Description
status string true
substate string false Additional state information
Enumerated Values
Property Value
status installing
status pause_before_installing
status downloading
status pause_before_rebooting
status rebooting
status pause_before_committing
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.myupdatebucket.com/image123",
      "expire": "2016-03-11T13:03:17.063493443Z"
    },
    "device_types_compatible": [
      "rspi",
      "rspi2",
      "rspi0"
    ]
  }
}

Properties
Name Type Required Description
id string true Deployment ID
artifact object true
» id string false
» 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 Array of log entries of a deployment
» timestamp string(date-time) true
» level string true
» message string true

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 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 POST https://hosted.mender.io/api/devices/v2/deployments/device/deployments/next \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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

const inputBody = '{
  "device_provides": {
    "device_type": "rspi",
    "artifact_name": "prototype-v1.0.0",
    "rootfs-image.checksum": "4d480539cdb23a4aee6330ff80673a5af92b7793eb1c57c4694532f96383b619"
  },
  "update_control_map": true
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/devices/v2/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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

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

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/devices/v2/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/v2/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{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/devices/v2/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.

Body parameter

{
  "device_provides": {
    "device_type": "rspi",
    "artifact_name": "prototype-v1.0.0",
    "rootfs-image.checksum": "4d480539cdb23a4aee6330ff80673a5af92b7793eb1c57c4694532f96383b619"
  },
  "update_control_map": true
}

Parameters

Name In Type Required Description
body body object true Request which describes the artifact(s) installed on the devices and the suppported features. The device_provides attribute contains a 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.
» device_provides 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.
» update_control_map body boolean false True if the device supports Update Control Maps.
Detailed descriptions

body: Request which describes the artifact(s) installed on the devices and the suppported features. The device_provides attribute contains a 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.

» device_provides: 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.

» update_control_map: True if the device supports Update Control Maps. NOTE: Available only in the Enterprise plan.

Example responses

200 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"
    ],
    "update_control_map": {
      "id": "e1ba5bee-c45d-11eb-887d-3fd47bdc3990",
      "priority": 1,
      "states": {
        "ArtifactInstall_Enter": {
          "action": "pause"
        }
      }
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successful response. DeploymentInstructions
204 No Content No updates for device. None
400 Bad Request Invalid Request. Error
409 Conflict Conflicting request data provided. Error
500 Internal Server Error Internal Server Error. Error

Get Update Control Map

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/devices/v2/deployments/device/deployments/{id}/update_control_map \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/devices/v2/deployments/device/deployments/{id}/update_control_map',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/devices/v2/deployments/device/deployments/{id}/update_control_map', 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/v2/deployments/device/deployments/{id}/update_control_map");
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{"Bearer {access-token}"},
    }

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

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

GET /device/deployments/{id}/update_control_map

Get the update control map object

Returns the update control map assigned to given, active deployment.

Parameters

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

Example responses

200 Response

{
  "update_control_map": {
    "id": "e1ba5bee-c45d-11eb-887d-3fd47bdc3990",
    "priority": 1,
    "states": {
      "ArtifactInstall_Enter": {
        "action": "pause"
      }
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successful response. UpdateControlMap
400 Bad Request Invalid Request. Error
404 Not Found Device deployment with given ID does not exist
or has been finished. #/components/responses/InvalidRequestError
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).

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"
    ],
    "update_control_map": {
      "id": "e1ba5bee-c45d-11eb-887d-3fd47bdc3990",
      "priority": 1,
      "states": {
        "ArtifactInstall_Enter": {
          "action": "pause"
        }
      }
    }
  }
}

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
update_control_map UpdateControlMap false A valid JSON object defining the update control map.
The ID attribute is automatically set to the deployment's ID.
NOTE: Available only in the Enterprise plan.

UpdateControlMap

{
  "update_control_map": {
    "id": "e1ba5bee-c45d-11eb-887d-3fd47bdc3990",
    "priority": 1,
    "states": {
      "ArtifactInstall_Enter": {
        "action": "pause"
      }
    }
  }
}

A valid JSON object defining the update control map. The ID attribute is automatically set to the deployment's ID. NOTE: Available only in the Enterprise plan.

Properties

None

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'

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'
};

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'
}

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'
}

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',
);

$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"},
    }

    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 accept or reject 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.
external_id string false External identity which can be used to verify devices managed by cloud providers.
Currently, only Azure IoT Edge devices are supported.

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 configure

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

Device facing API for managing persistent device connections.

Base URLs:

Get Device Configuration

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/devices/v1/deviceconfig/configuration \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/devices/v1/deviceconfig/configuration',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/devices/v1/deviceconfig/configuration', 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/deviceconfig/configuration");
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{"Bearer {access-token}"},
    }

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

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

GET /configuration

Query the configuration store; retrieve all key-value pairs

Example responses

200 Response

{
  "property1": "string",
  "property2": "string"
}

Responses

Status Meaning Description Schema
200 OK OK DeviceAPIConfiguration
400 Bad Request Bad Request. Error
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

Report Device Configuration

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/devices/v1/deviceconfig/configuration \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

PUT https://hosted.mender.io/api/devices/v1/deviceconfig/configuration HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "property1": "string",
  "property2": "string"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/devices/v1/deviceconfig/configuration',
{
  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' => 'Bearer {access-token}'
}

result = RestClient.put 'https://hosted.mender.io/api/devices/v1/deviceconfig/configuration',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.put('https://hosted.mender.io/api/devices/v1/deviceconfig/configuration', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/devices/v1/deviceconfig/configuration', 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/deviceconfig/configuration");
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{"Bearer {access-token}"},
    }

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

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

PUT /configuration

Set a key-value pair store, updating if existing, removing if empty

Body parameter

{
  "property1": "string",
  "property2": "string"
}

Parameters

Name In Type Required Description
body body DeviceAPIConfiguration false

Example responses

400 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content Created None
400 Bad Request Bad Request. Error
500 Internal Server Error Internal Server Error. Error

Schemas

DeviceAPIConfiguration

{
  "property1": "string",
  "property2": "string"
}

Properties
Name Type Required Description
additionalProperties string false

Error

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.
request_id string false Request ID passed with the request X-Men-Requestid header or generated by the server.

Device connect

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

Device facing API for managing persistent device connections.

Base URLs:

Connect

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/devices/v1/deviceconnect/connect \
  -H 'Accept: application/json' \
  -H 'Connection: Upgrade' \
  -H 'Upgrade: websocket' \
  -H 'Sec-Websocket-Key: string' \
  -H 'Sec-Websocket-Version: 13' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/devices/v1/deviceconnect/connect HTTP/1.1
Host: hosted.mender.io
Accept: application/json
Connection: Upgrade
Upgrade: websocket
Sec-Websocket-Key: string
Sec-Websocket-Version: 13


const headers = {
  'Accept':'application/json',
  'Connection':'Upgrade',
  'Upgrade':'websocket',
  'Sec-Websocket-Key':'string',
  'Sec-Websocket-Version':'13',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/devices/v1/deviceconnect/connect',
{
  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',
  'Connection' => 'Upgrade',
  'Upgrade' => 'websocket',
  'Sec-Websocket-Key' => 'string',
  'Sec-Websocket-Version' => '13',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Connection': 'Upgrade',
  'Upgrade': 'websocket',
  'Sec-Websocket-Key': 'string',
  'Sec-Websocket-Version': '13',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Connection' => 'Upgrade',
    'Upgrade' => 'websocket',
    'Sec-Websocket-Key' => 'string',
    'Sec-Websocket-Version' => '13',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/devices/v1/deviceconnect/connect', 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/deviceconnect/connect");
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"},
        "Connection": []string{"Upgrade"},
        "Upgrade": []string{"websocket"},
        "Sec-Websocket-Key": []string{"string"},
        "Sec-Websocket-Version": []string{"13"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

GET /connect

Connect the device and make it available to the server.

Calling /connect will upgrade the connection to a persistent websocket connection and make the device available to the management API. The device must provide DeviceJWT identity either as Authorization (Bearer) header or as a cookie named 'JWT'.

Parameters

Name In Type Required Description
Connection header string false Standard websocket request header.
Upgrade header string(base64) false Standard websocket request header.
Sec-Websocket-Key header string(base64) false Standard websocket request header.
Sec-Websocket-Version header integer false Standard websocket request header.
Enumerated Values
Parameter Value
Connection Upgrade
Upgrade websocket
Sec-Websocket-Version 13

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
101 Switching Protocols Successful response - change to websocket protocol. None
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error
Response Headers
Status Header Type Format Description
101 Sec-Websocket-Accept string base64 Standard websocket upgrade response header.
101 Upgrade string

Schemas

Error

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.
request_id string false Request ID passed with the request X-MEN-RequestID header or generated by the server.

Device monitor

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

Device facing API for monitoring.

Base URLs:

DeviceAlertPost

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/devices/v1/devicemonitor/alert \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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

const inputBody = '[
  {
    "name": "mender-connect systemd service",
    "level": "CRITICAL",
    "timestamp": "2019-07-21T17:32:28Z",
    "subject": {
      "name": "mender-connect",
      "status": "not-running",
      "type": "systemd.unit",
      "details": {
        "description": "Description of an error.",
        "lines_before": [
          {
            "line_number": 1,
            "data": "Line 1 from a log file"
          },
          {
            "line_number": 2,
            "data": "Line 2 from a log file"
          }
        ],
        "line_matching": {
          "line_number": 3,
          "data": "Line 3 from a log file"
        },
        "lines_after": [
          {
            "line_number": 4,
            "data": "Line 4 from a log file"
          },
          {
            "line_number": 5,
            "data": "Line 5 from a log file"
          }
        ]
      }
    }
  }
]';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/devices/v1/devicemonitor/alert',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

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

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/devices/v1/devicemonitor/alert', 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/devicemonitor/alert");
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{"Bearer {access-token}"},
    }

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

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

POST /alert

Process alert messages from a device.

HTTP POST to /alert endpoint originates from a device where a monitored entity reach a critical condition or switched from it to normal state. The JWT must be passed in the Authorization headers.

Body parameter

[
  {
    "name": "mender-connect systemd service",
    "level": "CRITICAL",
    "timestamp": "2019-07-21T17:32:28Z",
    "subject": {
      "name": "mender-connect",
      "status": "not-running",
      "type": "systemd.unit",
      "details": {
        "description": "Description of an error.",
        "lines_before": [
          {
            "line_number": 1,
            "data": "Line 1 from a log file"
          },
          {
            "line_number": 2,
            "data": "Line 2 from a log file"
          }
        ],
        "line_matching": {
          "line_number": 3,
          "data": "Line 3 from a log file"
        },
        "lines_after": [
          {
            "line_number": 4,
            "data": "Line 4 from a log file"
          },
          {
            "line_number": 5,
            "data": "Line 5 from a log file"
          }
        ]
      }
    }
  }
]

Parameters

Name In Type Required Description
body body Alert true

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content The service processed the alert. None
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error

Set Monitor Configuration

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/devices/v1/devicemonitor/config \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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

const inputBody = '[
  {
    "name": "string",
    "status": "string",
    "type": "string"
  }
]';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/devices/v1/devicemonitor/config',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

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

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/devices/v1/devicemonitor/config', 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/devicemonitor/config");
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{"Bearer {access-token}"},
    }

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

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

POST /config

Store Monitor configuration from a device.

Submit the current monitor configuration from the device. The JWT must be passed in the Authorization headers.

Body parameter

[
  {
    "name": "string",
    "status": "string",
    "type": "string"
  }
]

Parameters

Name In Type Required Description
body body MonitorConfiguration true

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content The service saved given configuration data. None
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error

Schemas

Error

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.
request_id string false Request ID passed with the request X-MEN-RequestID header or generated by the server.

Alert

{
  "name": "mender-connect systemd service",
  "level": "CRITICAL",
  "timestamp": "2019-07-21T17:32:28Z",
  "subject": {
    "name": "mender-connect",
    "status": "not-running",
    "type": "systemd.unit",
    "details": {
      "description": "Description of an error.",
      "lines_before": [
        {
          "line_number": 1,
          "data": "Line 1 from a log file"
        },
        {
          "line_number": 2,
          "data": "Line 2 from a log file"
        }
      ],
      "line_matching": {
        "line_number": 3,
        "data": "Line 3 from a log file"
      },
      "lines_after": [
        {
          "line_number": 4,
          "data": "Line 4 from a log file"
        },
        {
          "line_number": 5,
          "data": "Line 5 from a log file"
        }
      ]
    }
  }
}

Alert request

Properties
Name Type Required Description
name string true A descriptive name of the alert
level string true Alert severity level
subject AlertSubject true Alert subject: the description of the alert origin
timestamp string(date-time) true Time and date when the alert occured
Enumerated Values
Property Value
level OK
level CRITICAL

AlertSubject

{
  "name": "mender-connect",
  "status": "not-running",
  "type": "systemd.unit",
  "details": {
    "description": "Description of an error.",
    "lines_before": [
      {
        "line_number": 1,
        "data": "Line 1 from a log file"
      },
      {
        "line_number": 2,
        "data": "Line 2 from a log file"
      }
    ],
    "line_matching": {
      "line_number": 3,
      "data": "Line 3 from a log file"
    },
    "lines_after": [
      {
        "line_number": 4,
        "data": "Line 4 from a log file"
      },
      {
        "line_number": 5,
        "data": "Line 5 from a log file"
      }
    ]
  }
}

Alert subject: the description of the alert origin

Properties
Name Type Required Description
name string true Name of an entity that caused the alert
type string true The type of executable that triggered the alert.
status string true Status of an entity that caused the alert
details AlertDetails false Additional details on the alert.

AlertDetails

{
  "description": "Description of an error.",
  "lines_before": [
    {
      "line_number": 1,
      "data": "Line 1 from a log file"
    },
    {
      "line_number": 2,
      "data": "Line 2 from a log file"
    }
  ],
  "line_matching": {
    "line_number": 3,
    "data": "Line 3 from a log file"
  },
  "lines_after": [
    {
      "line_number": 4,
      "data": "Line 4 from a log file"
    },
    {
      "line_number": 5,
      "data": "Line 5 from a log file"
    }
  ]
}

Additional details on the alert.

Properties
Name Type Required Description
description string false Alert description.
lines_before [LineDescriptor] false Log lines before matched pattern.
lines_after [LineDescriptor] false Log lines after matched pattern.
line_matching LineDescriptor false Describes the data and line of a pattern-matched log line.

LineDescriptor

{
  "line_number": 1,
  "data": "string"
}

Describes the data and line of a pattern-matched log line.

Properties
Name Type Required Description
line_number integer true
data string true

MonitorConfiguration

{
  "name": "string",
  "status": "string",
  "type": "string"
}

Monitor configuration data.

Properties
Name Type Required Description
name string true
status string true
type string true

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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

Replace Attributes

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/devices/v1/inventory/device/attributes \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

PUT 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':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/devices/v1/inventory/device/attributes',
{
  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' => 'Bearer {access-token}'
}

result = RestClient.put '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': 'Bearer {access-token}'
}

r = requests.put('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' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('PUT','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("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{"Bearer {access-token}"},
    }

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

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

PUT /device/attributes

Replace the set of attributes for a device

Replaces the attribute set for the authenticated device with the provided one. The device ID is retrieved from the authorization header.

This method replaces all the attributes with the new set:

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).

Management APIs

Audit Logs service

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 user-facing API to audit logs service.

Base URLs:

Get Audit Logs

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/auditlogs/logs \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/auditlogs/logs',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/auditlogs/logs', 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/auditlogs/logs");
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{"Bearer {access-token}"},
    }

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

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

GET /logs

Returns a paged list of audit log objects.

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.
created_before query number(integer) false List only log entries created before and equal to Unix timestamp (UTC)
created_after query number(integer) false List only log entries created after and equal to Unix timestamp (UTC)
actor_id query string false If present, limits the results only to logs where the actor has a given id.
actor_type query string false If present, limits the results only to logs where the actor is of a given type.
actor_email query string false If present, limits the results only to logs where the actor has a given email address.
object_id query string false If present, limits the results only to logs where the object has a given id.
object_type query string false If present, limits the results only to logs where the object is of a given type.
object_deployment_name query string false If present, limits the results only to logs where the object is a deployment and has a given name.
sort query string false Supports sorting the log list by creation date.
Detailed descriptions

sort: Supports sorting the log list by creation date. By default logs are sorted by creation date in descending order (newest first).

Enumerated Values
Parameter Value
actor_type user
actor_type device
object_type user
object_type deployment
object_type artifact
object_type device
sort asc
sort desc

Example responses

200 Response

[
  {
    "actor": {
      "id": "string",
      "type": "user",
      "email": "string",
      "identity_data": "string"
    },
    "time": "2019-08-24T14:15:22Z",
    "action": "create",
    "object": {
      "id": "string",
      "type": "user",
      "user": {
        "email": "user@acme.com"
      },
      "deployment": {
        "application/json": {
          "name": "production",
          "artifact_name": "Application 0.0.1"
        }
      },
      "device": {
        "id": "e1ba5bee-c45d-11eb-887d-3fd47bdc3990",
        "identity_data": "{\"mac_address\": \"2C:54:91:88:C9:E3\", \"sn\": \"1229224105105176\"}"
      }
    },
    "change": "string"
  }
]

Responses

Status Meaning Description Schema
200 OK Successful response. Inline
401 Unauthorized The user cannot be granted authentication. Error
429 Too Many Requests The user has sent too many requests in a given amount of time. Error
500 Internal Server Error Internal Server Error. Error
Response Schema

Status Code 200

ListOfLogs

Name Type Required Restrictions Description
ListOfLogs [AuditLog] false A list of audit logs is returned.
» actor Actor true The actor may be a user or device.
Depending on the type of the actor different information will be available.
»» id string true An unique identifier of the actor.
»» type string true The type of the actor.
»» email string false The email address of the user.
»» identity_data string false The Indentity data of the device.
» time string(date-time) true
» action string true
» object Object true Various types of objects are supported.
Depending on the type of object different information will be available.
»» id string true An unique identifier of the object.
»» type string true The type of the object.
»» user User false User descriptor.
»»» email string true Email address of the user.
»» deployment Deployment false The deployment descriptor.
»»» name string true
»»» artifact_name string true
»» device Device false Device descriptor.
»»» id string false Device ID.
»»» identity_data string true Vendor-specific JSON representation of the device identity data (MACs, serial numbers, etc.).
» change string false
Enumerated Values
Property Value
type user
type device
action create
action update
action delete
action abort
action reject
action decommission
type user
type deployment
type artifact
type device
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.

Export Audit Logs

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/auditlogs/logs/export \
  -H 'Accept: text/csv' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v1/auditlogs/logs/export HTTP/1.1
Host: hosted.mender.io
Accept: text/csv


const headers = {
  'Accept':'text/csv',
  'Authorization':'Bearer {access-token}'
};

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

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'text/csv',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'text/csv',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'text/csv',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/auditlogs/logs/export', 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/auditlogs/logs/export");
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{"text/csv"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

GET /logs/export

Returns a paged list of audit log objects.

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

Parameters

Name In Type Required Description
limit query number(integer) false Limit number of logs returned
created_before query number(integer) false List only log entries created before and equal to Unix timestamp (UTC)
created_after query number(integer) false List only log entries created after and equal to Unix timestamp (UTC)
actor_id query string false If present, limits the results only to logs where the actor has a given id.
actor_type query string false If present, limits the results only to logs where the actor is of a given type.
actor_email query string false If present, limits the results only to logs where the actors has a given email address.
object_id query string false If present, limits the results only to logs where the object has a given id.
object_type query string false If present, limits the results only to logs where the object is of a given type.
object_deployment_name query string false If present, limits the results only to logs where the object is a deployment and has a given name.
sort query string false Supports sorting the log list by creation date.
format_separator query string false Format string used to separate nested fields in the exported csv header
ignore query string false Header fields to ignore in the exported document (e.g. ignore=actor.id)
Detailed descriptions

sort: Supports sorting the log list by creation date. By default logs are sorted by creation date in descending order (newest first).

format_separator: Format string used to separate nested fields in the exported csv header

ignore: Header fields to ignore in the exported document (e.g. ignore=actor.id)

Enumerated Values
Parameter Value
actor_type user
actor_type device
object_type user
object_type deployment
object_type artifact
object_type device
sort asc
sort desc

Example responses

401 Response

Responses

Status Meaning Description Schema
200 OK Successful response.

Document follows in response body (chunked encoding).|None| |401|Unauthorized|The user cannot be granted authentication.|Error| |429|Too Many Requests|The user has sent too many requests in a given amount of time.|Error| |500|Internal Server Error|Internal Server Error.|Error|

Schemas

AuditLog

{
  "actor": {
    "id": "string",
    "type": "user",
    "email": "string",
    "identity_data": "string"
  },
  "time": "2019-08-24T14:15:22Z",
  "action": "create",
  "object": {
    "id": "string",
    "type": "user",
    "user": {
      "email": "user@acme.com"
    },
    "deployment": {
      "application/json": {
        "name": "production",
        "artifact_name": "Application 0.0.1"
      }
    },
    "device": {
      "id": "e1ba5bee-c45d-11eb-887d-3fd47bdc3990",
      "identity_data": "{\"mac_address\": \"2C:54:91:88:C9:E3\", \"sn\": \"1229224105105176\"}"
    }
  },
  "change": "string"
}

The audit log.

Properties
Name Type Required Description
actor Actor true The actor may be a user or device.
Depending on the type of the actor different information will be available.
time string(date-time) true
action string true
object Object true Various types of objects are supported.
Depending on the type of object different information will be available.
change string false
Enumerated Values
Property Value
action create
action update
action delete
action abort
action reject
action decommission

Actor

{
  "id": "string",
  "type": "user",
  "email": "string",
  "identity_data": "string"
}

The actor may be a user or device. Depending on the type of the actor different information will be available.

Properties
Name Type Required Description
id string true An unique identifier of the actor.
type string true The type of the actor.
email string false The email address of the user.
identity_data string false The Indentity data of the device.
Enumerated Values
Property Value
type user
type device

Object

{
  "id": "string",
  "type": "user",
  "user": {
    "email": "user@acme.com"
  },
  "deployment": {
    "application/json": {
      "name": "production",
      "artifact_name": "Application 0.0.1"
    }
  },
  "device": {
    "id": "e1ba5bee-c45d-11eb-887d-3fd47bdc3990",
    "identity_data": "{\"mac_address\": \"2C:54:91:88:C9:E3\", \"sn\": \"1229224105105176\"}"
  }
}

Various types of objects are supported. Depending on the type of object different information will be available.

Properties
Name Type Required Description
id string true An unique identifier of the object.
type string true The type of the object.
user User false User descriptor.
deployment Deployment false The deployment descriptor.
device Device false Device descriptor.
Enumerated Values
Property Value
type user
type deployment
type artifact
type device

User

{
  "email": "user@acme.com"
}

User descriptor.

Properties
Name Type Required Description
email string true Email address of the user.

Deployment

{
  "application/json": {
    "name": "production",
    "artifact_name": "Application 0.0.1"
  }
}

The deployment descriptor.

Properties
Name Type Required Description
name string true
artifact_name string true

Device

{
  "id": "e1ba5bee-c45d-11eb-887d-3fd47bdc3990",
  "identity_data": "{\"mac_address\": \"2C:54:91:88:C9:E3\", \"sn\": \"1229224105105176\"}"
}

Device descriptor.

Properties
Name Type Required Description
id string false Device ID.
identity_data string true Vendor-specific JSON representation of the device identity data (MACs, serial numbers, etc.).

Error

{
  "error": "error description"
}

The error descriptor.

Properties
Name Type Required Description
error string false The description of the error.

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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.
type query string false Deployment type 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)
sort query string false Supports sorting the deployments list by creation date.
Detailed descriptions

type: Deployment type filter.

sort: Supports sorting the deployments list by creation date.

Enumerated Values
Parameter Value
status inprogress
status finished
status pending
status scheduled
type software
type configuration
sort asc
sort desc

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
» id string true Deployment identifier
» name string true Name of the deployment
» artifact_name string true Name of the artifact to deploy
» created string(date-time) true Deployment's creation date and time
» finished string(date-time) false Deployment's completion date and time
» status string true Status of the deployment
» device_count integer true Number of devices the deployment acted upon
» artifacts [string] false An array of artifact's identifiers.
» groups [string] false An array of groups the devices targeted by the deployment belong to.
Available only if the user created the deployment for a group or a single device (if the device was in a static group).
» 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
» update_control_map object false A valid JSON object defining the update control map.
NOTE: Available only in the Enterprise plan.
» 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.
» type string false
» configuration string false A string containing a configuration object provided
with the deployment constructor.
» autogenerate_delta boolean false The flag idicating if the autogeneration of delta artifacts is enabled for a given deployment.
» statistics DeploymentStatistics false
»» status DeploymentStatusStatistics false
»»» 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.
»»» pause_before_installing integer true Number of deployments paused before install state.
»»» pause_before_rebooting integer true Number of deployments paused before reboot phase.
»»» pause_before_committing integer true Number of deployments paused before commit phase.
»» total_size integer false Sum of sizes (in bytes) of all artifacts assigned to all device deployments,
which are part of this deployment.
If the same artifact is assigned to multiple device deployments,
its size will be counted multiple times.
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
type configuration
type software
Response Headers
Status Header Type Format Description
200 Link string Standard header, we support 'first', 'next', and 'prev'.
200 X-Total-Count integer Total number of deployments matching query.

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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
409 Conflict An active deployment with the same parameters already exists. 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.

Deployment Status Statistics List

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/deployments/deployments/statistics/list \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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

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

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments/statistics/list',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

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

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/statistics/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/statistics/list");
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{"Bearer {access-token}"},
    }

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

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

POST /deployments/statistics/list

*Get status count for all devices in the listed deployments (plural). *

Body parameter

{
  "deployment_ids": [
    "string"
  ]
}

Parameters

Name In Type Required Description
body body DeploymentIdentifier true

Example responses

OK

[
  {
    "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
    "stats": {
      "success": 3,
      "pending": 1,
      "failure": 0,
      "downloading": 1,
      "installing": 2,
      "rebooting": 3,
      "noartifact": 0,
      "already-installed": 0,
      "aborted": 0,
      "pause_before_installing": 1,
      "pause_before_rebooting": 1,
      "pause_before_committing": 1
    }
  },
  {
    "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
    "stats": {
      "success": 3,
      "pending": 1,
      "failure": 0,
      "downloading": 1,
      "installing": 2,
      "rebooting": 3,
      "noartifact": 0,
      "already-installed": 0,
      "aborted": 0,
      "pause_before_installing": 1,
      "pause_before_rebooting": 1,
      "pause_before_committing": 1
    }
  }
]

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 OK 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

Status Code 200

Name Type Required Restrictions Description
» id string false The deployment ID
» stats DeploymentStatusStatistics false
»» 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.
»» pause_before_installing integer true Number of deployments paused before install state.
»» pause_before_rebooting integer true Number of deployments paused before reboot phase.
»» pause_before_committing integer true Number of deployments paused before commit phase.

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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

Patch Deployment Control Map

Code samples

# You can also use wget
curl -X PATCH https://hosted.mender.io/api/management/v1/deployments/deployments/{id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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

const inputBody = '{
  "update_control_map": {}
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments/{id}',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

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

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('PATCH','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("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{"Bearer {access-token}"},
    }

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

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

PATCH /deployments/{id}

Update the deployment's update control map

Updates the deployment's update control map. It is possible to update the deployment's update control map only if the map exists. In case the control map does not exist, 409 Conflict error will be returned.

Body parameter

{
  "update_control_map": {}
}

Parameters

Name In Type Required Description
id path string true Deployment identifier.
body body object true Update control map to set.
» update_control_map body object 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 Control map updated. None
400 Bad Request Invalid Request. Error
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
409 Conflict An active deployment with the same parameters already exists. 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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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,
  "pause_before_installing": 1,
  "pause_before_rebooting": 1,
  "pause_before_committing": 1
}

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 DeploymentStatusStatistics
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

List All 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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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

*DEPRECATED: this end-point is deprecated because it doesn't support pagination and will be removed in the future, please use the /deployments/{deployment_id}/devices/list end-point instead. *

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",
    "started": "2016-02-12T13:03:17.063493443Z",
    "device_type": "Raspberry Pi 3",
    "log": false,
    "state": "installing",
    "substate": "installing.enter;script:foo-bar",
    "image": {
      "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
      "name": "Application 1.0.0",
      "meta": {
        "description": "Johns Monday test build"
      },
      "meta_artifact": {
        "name": "Application 1.0.0",
        "device_types_compatible": [
          "Beagle Bone"
        ],
        "info": {
          "format": "mender",
          "version": 3
        },
        "signed": false,
        "updates": [
          {
            "type_info": {
              "type": "rootfs-image"
            },
            "files": [
              {
                "name": "rootfs-image-1",
                "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                "size": 123,
                "date": "2016-03-11T13:03:17.063+0000"
              }
            ],
            "meta_data": {}
          }
        ],
        "artifact_provides": {
          "artifact_name": "test",
          "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
          "rootfs-image.version": "test"
        },
        "artifact_depends": {
          "device_type": [
            "test"
          ]
        },
        "clears_artifact_provides": [
          "rootfs-image.*"
        ]
      },
      "size": 36891648,
      "modified": "2016-03-11T13:03:17.063493443Z"
    }
  }
]

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 [DeviceWithImage] false
» id string true Device identifier.
» status DeviceStatus true
» created string(date-time) false
» started string(date-time) false
» finished string(date-time) false
» deleted 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
» image object false
»» id string false Image ID
»» meta object false
»»» description string false Image description
»» meta_artifact object false
»»» name string false
»»» device_types_compatible [string] false An array of compatible device types.
»»» info ArtifactInfo false Information about artifact format and version.
»»»» format string false
»»»» version integer false
»»» signed boolean false Idicates if artifact is signed or not.
»»» updates [Update] false [Single updated to be applied.
]
»»»» type_info ArtifactTypeInfo false Information about update type.
»»»»» type string false Note that for emtpy Artifacts, the type is 'null'
»»»» 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)
»»» artifact_provides object false List of Artifact provides.

Map of key/value pairs, where both keys and values are strings.
»»»» additionalProperties string false
»»» artifact_depends object false List of Artifact depends.

Map of key/value pairs, where keys are strings and values are lists of strings.
»»»» additionalProperties [string] false
»»» clears_artifact_provides [string] false List of Clear Artifact provides.
»» size integer false Image size in bytes
»» modified string(date-time) false Creation / last edition of any of the artifact properties
Enumerated Values
Property Value
status failure
status aborted
status pause_before_installing
status pause_before_committing
status pause_before_rebooting
status downloading
status installing
status rebooting
status pending
status success
status noartifact
status already-installed
status decommissioned

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/list \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices/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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/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/{deployment_id}/devices/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{"Bearer {access-token}"},
    }

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

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

GET /deployments/{deployment_id}/devices/list

*Get the list of devices and their respective status for the deployment with the given ID. The response includes devices as they get assigned to the deployment when checking for updates. Therefore, this endpoint will list all the devices only once each asks for updates and evaluates this deployment. *

Parameters

Name In Type Required Description
deployment_id path string true Deployment identifier.
status query string false Filter devices by status within deployment.
page query number(integer) false Starting page.
per_page query number(integer) false Maximum number of results per page.
Enumerated Values
Parameter Value
status failure
status aborted
status pause_before_installing
status pause_before_committing
status pause_before_rebooting
status downloading
status installing
status rebooting
status pending
status success
status noartifact
status already-installed
status decommissioned
status pause
status active
status finished

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",
    "started": "2016-02-12T13:03:17.063493443Z",
    "device_type": "Raspberry Pi 3",
    "log": false,
    "state": "installing",
    "substate": "installing.enter;script:foo-bar",
    "image": {
      "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
      "name": "Application 1.0.0",
      "meta": {
        "description": "Johns Monday test build"
      },
      "meta_artifact": {
        "name": "Application 1.0.0",
        "device_types_compatible": [
          "Beagle Bone"
        ],
        "info": {
          "format": "mender",
          "version": 3
        },
        "signed": false,
        "updates": [
          {
            "type_info": {
              "type": "rootfs-image"
            },
            "files": [
              {
                "name": "rootfs-image-1",
                "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                "size": 123,
                "date": "2016-03-11T13:03:17.063+0000"
              }
            ],
            "meta_data": {}
          }
        ],
        "artifact_provides": {
          "artifact_name": "test",
          "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
          "rootfs-image.version": "test"
        },
        "artifact_depends": {
          "device_type": [
            "test"
          ]
        },
        "clears_artifact_provides": [
          "rootfs-image.*"
        ]
      },
      "size": 36891648,
      "modified": "2016-03-11T13:03:17.063493443Z"
    }
  }
]

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 [DeviceWithImage] false
» id string true Device identifier.
» status DeviceStatus true
» created string(date-time) false
» started string(date-time) false
» finished string(date-time) false
» deleted 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
» image object false
»» id string false Image ID
»» meta object false
»»» description string false Image description
»» meta_artifact object false
»»» name string false
»»» device_types_compatible [string] false An array of compatible device types.
»»» info ArtifactInfo false Information about artifact format and version.
»»»» format string false
»»»» version integer false
»»» signed boolean false Idicates if artifact is signed or not.
»»» updates [Update] false [Single updated to be applied.
]
»»»» type_info ArtifactTypeInfo false Information about update type.
»»»»» type string false Note that for emtpy Artifacts, the type is 'null'
»»»» 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)
»»» artifact_provides object false List of Artifact provides.

Map of key/value pairs, where both keys and values are strings.
»»»» additionalProperties string false
»»» artifact_depends object false List of Artifact depends.

Map of key/value pairs, where keys are strings and values are lists of strings.
»»»» additionalProperties [string] false
»»» clears_artifact_provides [string] false List of Clear Artifact provides.
»» size integer false Image size in bytes
»» modified string(date-time) false Creation / last edition of any of the artifact properties
Enumerated Values
Property Value
status failure
status aborted
status pause_before_installing
status pause_before_committing
status pause_before_rebooting
status downloading
status installing
status rebooting
status pending
status success
status noartifact
status already-installed
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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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

Status Code 200

List of device IDs

Name Type Required Restrictions Description

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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

The response body for this endpoint include the device's deployment logs in text/plain format.

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, including the logs in text/plain format. None
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

Get Delta Generation Status

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices/{device_id}/delta/status \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices/{device_id}/delta/status HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices/{device_id}/delta/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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://hosted.mender.io/api/management/v1/deployments/deployments/{deployment_id}/devices/{device_id}/delta/status', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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}/delta/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}/devices/{device_id}/delta/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{"Bearer {access-token}"},
    }

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

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

GET /deployments/{deployment_id}/devices/{device_id}/delta/status

Get the detailed status of server side delta generation

The response body for this endpoint include a detailed information on the delta generation job.

Parameters

Name In Type Required Description
deployment_id path string true Deployment identifier.
device_id path string true Device identifier.

Example responses

200 Response

{
  "id": "string",
  "workflowName": "string",
  "inputParameters": [
    {
      "name": "key",
      "value": "parameter"
    }
  ],
  "status": "string",
  "results": [
    {
      "success": true,
      "cli": {
        "command": [
          "string"
        ],
        "output": "string",
        "error": "string",
        "exitCode": 0
      },
      "request": {
        "statusCode": 0,
        "body": "string"
      },
      "response": {
        "uri": "string",
        "method": "string",
        "headers": [
          "string"
        ],
        "body": "string"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successful response, including the status in application/json format. JobStatus
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

List Deployments for a Device

Code samples

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

GET 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':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments/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' => 'Bearer {access-token}'
}

result = RestClient.get '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': 'Bearer {access-token}'
}

r = requests.get('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' => 'Bearer {access-token}',
);

$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/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("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{"Bearer {access-token}"},
    }

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

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

GET /deployments/devices/{id}

Return the Deployments history for a Device

Return the Deployments history for the specified Device, listing all its Deployments.

Parameters

Name In Type Required Description
id path string true System wide device identifier
status query string false Filter deployments by status for the given device.
page query number(integer) false Starting page.
per_page query number(integer) false Maximum number of results per page.
Enumerated Values
Parameter Value
status failure
status aborted
status pause_before_installing
status pause_before_committing
status pause_before_rebooting
status downloading
status installing
status rebooting
status pending
status success
status noartifact
status already-installed
status decommissioned
status pause
status active
status finished

Example responses

200 Response

[
  {
    "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
    "deployment": {
      "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
      "name": "production",
      "artifact_name": "Application 0.0.1",
      "status": "inprogress",
      "created": "2016-02-11T13:03:17.063493443Z",
      "device_count": 100
    },
    "device": {
      "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
      "device_type": "Raspberry Pi 3",
      "status": "installing",
      "finished": "2016-03-11T13:03:17.063493443Z",
      "created": "2016-02-11T13:03:17.063493443Z",
      "started": "2016-02-11T13:03:17.063493443Z",
      "state": "installing",
      "substate": "installing.enter;script:foo-bar",
      "log": false,
      "image": {
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "name": "Application 1.0.0",
        "meta": {
          "description": "Johns Monday test build"
        },
        "meta_artifact": {
          "name": "Application 1.0.0",
          "device_types_compatible": [
            "Beagle Bone"
          ],
          "info": {
            "format": "mender",
            "version": 3
          },
          "signed": false,
          "updates": [
            {
              "type_info": {
                "type": "rootfs-image"
              },
              "files": [
                {
                  "name": "rootfs-image-1",
                  "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                  "size": 123,
                  "date": "2016-03-11T13:03:17.063+0000"
                }
              ],
              "meta_data": {}
            }
          ],
          "artifact_provides": {
            "artifact_name": "test",
            "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
            "rootfs-image.version": "test"
          },
          "artifact_depends": {
            "device_type": [
              "test"
            ]
          },
          "clears_artifact_provides": [
            "rootfs-image.*"
          ]
        },
        "size": 36891648,
        "modified": "2016-03-11T13:03:17.063493443Z"
      }
    }
  }
]

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 [DeviceDeployment] false
» id string false
» deployment Deployment true
»» id string true Deployment identifier
»» name string true Name of the deployment
»» artifact_name string true Name of the artifact to deploy
»» created string(date-time) true Deployment's creation date and time
»» finished string(date-time) false Deployment's completion date and time
»» status string true Status of the deployment
»» device_count integer true Number of devices the deployment acted upon
»» artifacts [string] false An array of artifact's identifiers.
»» groups [string] false An array of groups the devices targeted by the deployment belong to.
Available only if the user created the deployment for a group or a single device (if the device was in a static group).
»» 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
»» update_control_map object false A valid JSON object defining the update control map.
NOTE: Available only in the Enterprise plan.
»» 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.
»» type string false
»» configuration string false A string containing a configuration object provided
with the deployment constructor.
»» autogenerate_delta boolean false The flag idicating if the autogeneration of delta artifacts is enabled for a given deployment.
»» statistics DeploymentStatistics false
»»» status DeploymentStatusStatistics false
»»»» 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.
»»»» pause_before_installing integer true Number of deployments paused before install state.
»»»» pause_before_rebooting integer true Number of deployments paused before reboot phase.
»»»» pause_before_committing integer true Number of deployments paused before commit phase.
»»» total_size integer false Sum of sizes (in bytes) of all artifacts assigned to all device deployments,
which are part of this deployment.
If the same artifact is assigned to multiple device deployments,
its size will be counted multiple times.
» device DeviceWithImage true
»» id string true Device identifier.
»» status DeviceStatus true
»» created string(date-time) false
»» started string(date-time) false
»» finished string(date-time) false
»» deleted 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
»» image object false
»»» id string false Image ID
»»» meta object false
»»»» description string false Image description
»»» meta_artifact object false
»»»» name string false
»»»» device_types_compatible [string] false An array of compatible device types.
»»»» info ArtifactInfo false Information about artifact format and version.
»»»»» format string false
»»»»» version integer false
»»»» signed boolean false Idicates if artifact is signed or not.
»»»» updates [Update] false [Single updated to be applied.
]
»»»»» type_info ArtifactTypeInfo false Information about update type.
»»»»»» type string false Note that for emtpy Artifacts, the type is 'null'
»»»»» 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)
»»»» artifact_provides object false List of Artifact provides.

Map of key/value pairs, where both keys and values are strings.
»»»»» additionalProperties string false
»»»» artifact_depends object false List of Artifact depends.

Map of key/value pairs, where keys are strings and values are lists of strings.
»»»»» additionalProperties [string] false
»»»» clears_artifact_provides [string] false List of Clear Artifact provides.
»»» size integer false Image size in bytes
»»» modified string(date-time) false Creation / last edition of any of the artifact properties
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
type configuration
type software
status failure
status aborted
status pause_before_installing
status pause_before_committing
status pause_before_rebooting
status downloading
status installing
status rebooting
status pending
status success
status noartifact
status already-installed
status decommissioned

Abort Deployments for a Device

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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}

Abort all the active and pending Deployments for a Device

Abort all the active and pending Deployments for the specified Device.

Please note that deployments for the Device not targeting it when issuing this API call won't be aborted. If the deployment applies to the Device in the future, for example, because of inventory updates, the Device will still process the deployment.

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 Operation completed successfully. None
401 Unauthorized Unauthorized. None
500 Internal Server Error Internal server error. Error

Reset Device Deployments history

Code samples

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

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments/devices/{id}/history',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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}/history', 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}/history");
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{"Bearer {access-token}"},
    }

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

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

DELETE /deployments/devices/{id}/history

Reset the Device Deployments history

Mark as logically deleted the completed Device Deployments records for the given device. This effectively resets the Device Deployments history and makes the device eligible (again) for all the active deployments.

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 Operation completed successfully. 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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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.

DEPRECATED: this end-point is deprecated because it doesn't support pagination and will be removed in the future, please use the /deployments/releases/list end-point instead.

Parameters

Name In Type Required Description
name query string false Release name filter.
description query string false Release description filter.
device_type query string false Release device type filter.
update_type query string false Update type filter.

Example responses

Successful response.

[
  {
    "name": "my-app-v1.0.1",
    "artifacts": [
      {
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "name": "Application 1.0.0",
        "description": "Johns Monday test build",
        "device_types_compatible": [
          "Beagle Bone"
        ],
        "info": {
          "format": "mender",
          "version": 3
        },
        "signed": false,
        "updates": [
          {
            "type_info": {
              "type": "rootfs-image"
            },
            "files": [
              {
                "name": "rootfs-image-1",
                "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                "size": 123,
                "date": "2016-03-11T13:03:17.063+0000"
              }
            ],
            "meta_data": {}
          }
        ],
        "artifact_provides": {
          "artifact_name": "test",
          "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
          "rootfs-image.version": "test"
        },
        "artifact_depends": {
          "device_type": [
            "test"
          ]
        },
        "clears_artifact_provides": [
          "rootfs-image.*"
        ],
        "size": 36891648,
        "modified": "2016-03-11T13:03:17.063493443Z"
      },
      {
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "name": "Application 1.0.0",
        "description": "Johns Monday test build",
        "device_types_compatible": [
          "Raspberry Pi"
        ],
        "info": {
          "format": "mender",
          "version": 3
        },
        "signed": false,
        "updates": [
          {
            "type_info": {
              "type": "rootfs-image"
            },
            "files": [
              {
                "name": "rootfs-image-1",
                "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                "size": 123,
                "date": "2016-03-11T13:03:17.063+0000"
              }
            ],
            "meta_data": {}
          }
        ],
        "artifact_provides": {
          "artifact_name": "test",
          "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
          "rootfs-image.version": "test"
        },
        "artifact_depends": {
          "device_type": [
            "test"
          ]
        },
        "clears_artifact_provides": [
          "rootfs-image.*"
        ],
        "size": 36891648,
        "modified": "2016-03-11T13:03:17.063493443Z"
      }
    ]
  },
  {
    "name": "my-app-v2.0.0",
    "artifacts": [
      {
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "name": "Application 2.0.0",
        "description": "Johns Monday test build",
        "device_types_compatible": [
          "Beagle Bone"
        ],
        "info": {
          "format": "mender",
          "version": 3
        },
        "signed": false,
        "updates": [
          {
            "type_info": {
              "type": "rootfs-image"
            },
            "files": [
              {
                "name": "rootfs-image-1",
                "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                "size": 123,
                "date": "2016-03-11T13:03:17.063+0000"
              }
            ],
            "meta_data": {}
          }
        ],
        "artifact_provides": {
          "artifact_name": "test",
          "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
          "rootfs-image.version": "test"
        },
        "artifact_depends": {
          "device_type": [
            "test"
          ]
        },
        "clears_artifact_provides": [
          "rootfs-image.*"
        ],
        "size": 36891648,
        "modified": "2016-03-11T13:03:17.063493443Z"
      }
    ]
  }
]

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 Releases with pagination

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deployments/deployments/releases/list \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/deployments/releases/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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/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/releases/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{"Bearer {access-token}"},
    }

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

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

GET /deployments/releases/list

*List releases with pagination *

Returns a collection of releases, allows filtering by release name and sorting by name or last modification date.

DEPRECATED: due to a mismatch in the capitalization of the fields of the response body and lack of support for advanced filters and sorting, we have deprecated this endpoint. Please use the v2 /deployments/releases end-point instead.

Parameters

Name In Type Required Description
name query string false Release name filter.
description query string false Release description filter.
device_type query string false Release device type filter.
update_type query string false Update type filter.
page query number(integer) false Starting page.
per_page query number(integer) false Maximum number of results per page.
sort query string false Sort the release list by the specified field and direction.
Detailed descriptions

sort: Sort the release list by the specified field and direction.

Enumerated Values
Parameter Value
sort artifacts_count:asc
sort artifacts_count:desc
sort modified:asc
sort modified:desc
sort name:asc
sort name:desc
sort tags:asc
sort tags:desc

Example responses

Successful response.

[
  {
    "name": "my-app-v1.0.1",
    "artifacts": [
      {
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "name": "Application 1.0.0",
        "description": "Johns Monday test build",
        "device_types_compatible": [
          "Beagle Bone"
        ],
        "info": {
          "format": "mender",
          "version": 3
        },
        "signed": false,
        "updates": [
          {
            "type_info": {
              "type": "rootfs-image"
            },
            "files": [
              {
                "name": "rootfs-image-1",
                "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                "size": 123,
                "date": "2016-03-11T13:03:17.063+0000"
              }
            ],
            "meta_data": {}
          }
        ],
        "artifact_provides": {
          "artifact_name": "test",
          "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
          "rootfs-image.version": "test"
        },
        "artifact_depends": {
          "device_type": [
            "test"
          ]
        },
        "clears_artifact_provides": [
          "rootfs-image.*"
        ],
        "size": 36891648,
        "modified": "2016-03-11T13:03:17.063493443Z"
      },
      {
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "name": "Application 1.0.0",
        "description": "Johns Monday test build",
        "device_types_compatible": [
          "Raspberry Pi"
        ],
        "info": {
          "format": "mender",
          "version": 3
        },
        "signed": false,
        "updates": [
          {
            "type_info": {
              "type": "rootfs-image"
            },
            "files": [
              {
                "name": "rootfs-image-1",
                "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                "size": 123,
                "date": "2016-03-11T13:03:17.063+0000"
              }
            ],
            "meta_data": {}
          }
        ],
        "artifact_provides": {
          "artifact_name": "test",
          "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
          "rootfs-image.version": "test"
        },
        "artifact_depends": {
          "device_type": [
            "test"
          ]
        },
        "clears_artifact_provides": [
          "rootfs-image.*"
        ],
        "size": 36891648,
        "modified": "2016-03-11T13:03:17.063493443Z"
      }
    ]
  },
  {
    "name": "my-app-v2.0.0",
    "artifacts": [
      {
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "name": "Application 2.0.0",
        "description": "Johns Monday test build",
        "device_types_compatible": [
          "Beagle Bone"
        ],
        "info": {
          "format": "mender",
          "version": 3
        },
        "signed": false,
        "updates": [
          {
            "type_info": {
              "type": "rootfs-image"
            },
            "files": [
              {
                "name": "rootfs-image-1",
                "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                "size": 123,
                "date": "2016-03-11T13:03:17.063+0000"
              }
            ],
            "meta_data": {}
          }
        ],
        "artifact_provides": {
          "artifact_name": "test",
          "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
          "rootfs-image.version": "test"
        },
        "artifact_depends": {
          "device_type": [
            "test"
          ]
        },
        "clears_artifact_provides": [
          "rootfs-image.*"
        ],
        "size": 36891648,
        "modified": "2016-03-11T13:03:17.063493443Z"
      }
    ]
  }
]

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
Response Headers
Status Header Type Format Description
200 Link string Standard header, we support 'first', 'next', and 'prev'.
200 X-Total-Count integer Total number of releases matching query.

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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 all the artifacts *

Returns a collection of all artifacts.

DEPRECATED: this end-point is deprecated because it doesn't support pagination and will be removed in the future, please use the /artifacts/list end-point instead.

Parameters

Name In Type Required Description
name query string false Release name filter.
description query string false Release description filter.
device_type query string false Release device type filter.

Example responses

200 Response

[
  {
    "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
    "name": "Application 1.0.0",
    "description": "Johns Monday test build",
    "device_types_compatible": [
      "Beagle Bone"
    ],
    "info": {
      "format": "mender",
      "version": 3
    },
    "signed": false,
    "updates": [
      {
        "type_info": {
          "type": "rootfs-image"
        },
        "files": [
          {
            "name": "rootfs-image-1",
            "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
            "size": 123,
            "date": "2016-03-11T13:03:17.063+0000"
          }
        ],
        "meta_data": {}
      }
    ],
    "artifact_provides": {
      "artifact_name": "test",
      "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
      "rootfs-image.version": "test"
    },
    "artifact_depends": {
      "device_type": [
        "test"
      ]
    },
    "clears_artifact_provides": [
      "rootfs-image.*"
    ],
    "size": 36891648,
    "modified": "2016-03-11T13:03:17.063493443Z"
  }
]

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.]
» id string true
» name string true
» description string true
» device_types_compatible [string] true An array of compatible device types.
» info ArtifactInfo false Information about artifact format and version.
»» format string false
»» version integer false
» signed boolean false Idicates if artifact is signed or not.
» updates [Update] false [Single updated to be applied.
]
»» type_info ArtifactTypeInfo false Information about update type.
»»» type string false Note that for emtpy Artifacts, the type is 'null'
»» 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)
» artifact_provides object false List of Artifact provides.

Map of key/value pairs, where both keys and values are strings.
»» additionalProperties string false
» artifact_depends object false List of Artifact depends.

Map of key/value pairs, where keys are strings and values are lists of strings.
»» additionalProperties [string] false
» clears_artifact_provides [string] false List of Clear Artifact provides.
» size number(integer) false Artifact total size in bytes - the size of the actual file that will be transferred to the device (compressed).
» modified string(date-time) true Represents creation / last edition of any of the artifact properties.

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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, v3.

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"
}

An artifact with the same name and matching dependency requirements already exists.

{
  "error": "an artifact with the same name and depends already exists",
  "request_id": "e4dde7e9-9424-4311-8648-86e24b542410",
  "metadata": {
    "conflict": {
      "want": "cookies"
    }
  }
}

Responses

Status Meaning Description Schema
201 Created Artifact uploaded. None
400 Bad Request Invalid Request. Error
401 Unauthorized Unauthorized. None
409 Conflict An artifact with the same name and matching dependency requirements already exists. ErrorExt
500 Internal Server Error Internal Server Error. Error
Response Headers
Status Header Type Format Description
201 Location string URL of the newly uploaded artifact.

List Artifacts with pagination

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deployments/artifacts/list \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/artifacts/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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/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/artifacts/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{"Bearer {access-token}"},
    }

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

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

GET /artifacts/list

*List known artifacts *

Returns a collection of all artifacts.

Parameters

Name In Type Required Description
name query string false Artifact name filter.
description query string false Artifact description filter.
device_type query string false Artifact device type filter.
page query number(integer) false Starting page.
per_page query number(integer) false Maximum number of results per page.
sort query string false Sort the artifact list by the specified field and direction.
Detailed descriptions

sort: Sort the artifact list by the specified field and direction.

Enumerated Values
Parameter Value
sort name:asc
sort name:desc
sort modified:asc
sort modified:desc

Example responses

200 Response

[
  {
    "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
    "name": "Application 1.0.0",
    "description": "Johns Monday test build",
    "device_types_compatible": [
      "Beagle Bone"
    ],
    "info": {
      "format": "mender",
      "version": 3
    },
    "signed": false,
    "updates": [
      {
        "type_info": {
          "type": "rootfs-image"
        },
        "files": [
          {
            "name": "rootfs-image-1",
            "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
            "size": 123,
            "date": "2016-03-11T13:03:17.063+0000"
          }
        ],
        "meta_data": {}
      }
    ],
    "artifact_provides": {
      "artifact_name": "test",
      "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
      "rootfs-image.version": "test"
    },
    "artifact_depends": {
      "device_type": [
        "test"
      ]
    },
    "clears_artifact_provides": [
      "rootfs-image.*"
    ],
    "size": 36891648,
    "modified": "2016-03-11T13:03:17.063493443Z"
  }
]

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.]
» id string true
» name string true
» description string true
» device_types_compatible [string] true An array of compatible device types.
» info ArtifactInfo false Information about artifact format and version.
»» format string false
»» version integer false
» signed boolean false Idicates if artifact is signed or not.
» updates [Update] false [Single updated to be applied.
]
»» type_info ArtifactTypeInfo false Information about update type.
»»» type string false Note that for emtpy Artifacts, the type is 'null'
»» 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)
» artifact_provides object false List of Artifact provides.

Map of key/value pairs, where both keys and values are strings.
»» additionalProperties string false
» artifact_depends object false List of Artifact depends.

Map of key/value pairs, where keys are strings and values are lists of strings.
»» additionalProperties [string] false
» clears_artifact_provides [string] false List of Clear Artifact provides.
» size number(integer) false Artifact total size in bytes - the size of the actual file that will be transferred to the device (compressed).
» modified string(date-time) true Represents creation / last edition of any of the artifact properties.
Response Headers
Status Header Type Format Description
200 Link string Standard header, we support 'first', 'next', and 'prev'.
200 X-Total-Count integer Total number of releases matching query.

Request Direct Upload

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/deployments/artifacts/directupload \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

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

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/directupload', 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/directupload");
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{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

POST /artifacts/directupload

Request link for uploading artifact directly to the storage backend. This is an on-prem endpoint only, not available on Hosted Mender.

Example responses

200 Response

{
  "id": "07d2e773-a2a3-4f64-936a-4245e79194dd",
  "uri": "https://hosted-mender-artifacts.s3.amazonaws.com/1234/40df67c4-e5e9-4042-981a-f43adebd5b88?X-Amz-Date=20230401T000000Z&X-Amz-Expires=900&X-Amz-Signature=6d656e646572",
  "expire": "2023-04-01T00:15:00Z"
}

Responses

Status Meaning Description Schema
200 OK OK ArtifactUploadLink
401 Unauthorized Unauthorized. None
500 Internal Server Error Internal Server Error. Error

Complete Direct Upload

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/deployments/artifacts/directupload/{id}/complete \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v1/deployments/artifacts/directupload/{id}/complete HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "size": 0,
  "updates": [
    {
      "type_info": {
        "type": "string"
      },
      "files": [
        {
          "name": "string",
          "checksum": "string",
          "size": 0,
          "date": "2019-08-24T14:15:22Z"
        }
      ],
      "meta_data": {}
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/artifacts/directupload/{id}/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',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

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

r = requests.post('https://hosted.mender.io/api/management/v1/deployments/artifacts/directupload/{id}/complete', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/directupload/{id}/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/deployments/artifacts/directupload/{id}/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"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

POST /artifacts/directupload/{id}/complete

Notify the server that the direct upload is completed to make it available in the artifacts API. Optionally you can provide files metadata which will be absent otherwise if skip-verify flag is present in the deployments service. This is an on-prem endpoint only, not available on Hosted Mender.

Body parameter

{
  "size": 0,
  "updates": [
    {
      "type_info": {
        "type": "string"
      },
      "files": [
        {
          "name": "string",
          "checksum": "string",
          "size": 0,
          "date": "2019-08-24T14:15:22Z"
        }
      ],
      "meta_data": {}
    }
  ]
}

Parameters

Name In Type Required Description
id path string true Artifact ID returned by "Request Direct Upload" API.
body body DirectUploadMetadata false Metadata for contents of the artifact.

Example responses

A pending direct upload with the given ID was not found.

{
  "error": "not found",
  "request_id": "b4965265-4475-4d00-8efc-840eaee5cf7b"
}

500 Response

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

Responses

Status Meaning Description Schema
202 Accepted Accepted None
401 Unauthorized Unauthorized. None
404 Not Found A pending direct upload with the given ID was not found. Inline
500 Internal Server Error Internal Server Error. Error
Response Schema

Status Code 404

Name Type Required Restrictions Description
» error string false
» request_id string(uuid) false Request identifier (Header: X-Men-Requestid)

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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 String that represents a JSON document defining the 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.
Detailed descriptions

» args: String that represents a JSON document defining the arguments used to generate the artifact. The service won't parse the content of this parameter and pass it as it is to the create artifact worker. The available arguments and options depend on the Update Module implementation and are, therefore, Type-specific.

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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.

{
  "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
  "name": "Application 1.0.0",
  "description": "Johns Monday test build",
  "device_types_compatible": [
    "Beagle Bone"
  ],
  "info": {
    "format": "mender",
    "version": 3
  },
  "signed": false,
  "updates": [
    {
      "type_info": {
        "type": "rootfs-image"
      },
      "files": [
        {
          "name": "rootfs-image-1",
          "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
          "size": 123,
          "date": "2016-03-11T13:03:17.063+0000"
        }
      ],
      "meta_data": {}
    }
  ],
  "artifact_provides": {
    "artifact_name": "test",
    "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
    "rootfs-image.version": "test"
  },
  "artifact_depends": {
    "device_type": [
      "test"
    ]
  },
  "clears_artifact_provides": [
    "rootfs-image.*"
  ],
  "size": 36891648,
  "modified": "2016-03-11T13:03:17.063493443Z"
}

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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

Get Configuration

Code samples

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

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/config',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/config', 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/config");
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{"Bearer {access-token}"},
    }

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

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

GET /config

Get the deployments service configuration

Example responses

200 Response

{
  "delta": {
    "enabled": true,
    "binary_delta": {
      "xdelta_args": {
        "disable_checksum": false,
        "disable_external_decompression": false,
        "compression_level": 6,
        "source_window_size": 0,
        "input_window_size": 0,
        "compression_duplicates_window": 0,
        "instruction_buffer_size": 0
      },
      "timeout": 0
    },
    "binary_delta_limits": {
      "xdelta_args_limits": {
        "compression_level": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "source_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "input_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "compression_duplicates_window": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "instruction_buffer_size": {
          "min": 5,
          "max": 100,
          "default": 10
        }
      },
      "timeout": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "jobs_in_parallel": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "queue_length": {
        "min": 5,
        "max": 100,
        "default": 10
      }
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successful response. Configuration
401 Unauthorized Unauthorized. None
500 Internal Server Error Internal Server Error. Error
Response Headers
Status Header Type Format Description
200 ETag string Contains the configuration object's current ETag.

Update Binary Delta configuration

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v1/deployments/config/binary_delta \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'If-Match: string' \
  -H 'Authorization: Bearer {access-token}'

PUT https://hosted.mender.io/api/management/v1/deployments/config/binary_delta HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json
If-Match: string

const inputBody = '{
  "xdelta_args": {
    "disable_checksum": false,
    "disable_external_decompression": false,
    "compression_level": 6,
    "source_window_size": 0,
    "input_window_size": 0,
    "compression_duplicates_window": 0,
    "instruction_buffer_size": 0
  },
  "timeout": 0
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'If-Match':'string',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deployments/config/binary_delta',
{
  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',
  'If-Match' => 'string',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'If-Match': 'string',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'If-Match' => 'string',
    'Authorization' => 'Bearer {access-token}',
);

$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/config/binary_delta', 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/config/binary_delta");
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"},
        "If-Match": []string{"string"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

PUT /config/binary_delta

Set the Binary Delta server-side generation configuration

Body parameter

{
  "xdelta_args": {
    "disable_checksum": false,
    "disable_external_decompression": false,
    "compression_level": 6,
    "source_window_size": 0,
    "input_window_size": 0,
    "compression_duplicates_window": 0,
    "instruction_buffer_size": 0
  },
  "timeout": 0
}

Parameters

Name In Type Required Description
If-Match header string false Contains the config current ETag, and performs the update only if it matches the one stored in the database.
body body BinaryDeltaConfiguration true Binary Delta server-side generation configuration.

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 Configuration updated. None
400 Bad Request The request body is malformed. Error
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
409 Conflict Delta generation is disabled. Error
412 Precondition Failed Document with a matching ETag does not exist. Error
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 true Description of the error.
request_id string false Request ID (same as in X-MEN-RequestID header).

ErrorExt

{
  "error": "error description",
  "request_id": "11de4197-d8cf-4bd2-8a3a-29f88f238e7b",
  "metadata": {
    "additional": "properties"
  }
}

Error descriptor with additional metadata.

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

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 Name of the deployment
artifact_name string true Name of the artifact to deploy
devices [string] false An array of devices' identifiers.
all_devices boolean false When set, the deployment will be created for all
currently accepted devices.
force_installation boolean false Force the installation of the Artifact disabling the already-installed check.
phases [NewDeploymentPhase] false [An array of deployments phases. Phases define a starting point and
a relative batch size of devices to which the deployment applies.

A single phase allows scheduling a deployment to start at a specific
time.

Multiple phases split the deployment into smaller batches of devices
at the time giving a higher level of control of the rate devices are
updated.

NOTE: Professional plan is only allowed to specify a single phase to
schedule deployments, this feature is not available for Starter plan.
]
professional, enterprise
retries integer false The number of times a device can retry the deployment in case of failure, defaults to 0
update_control_map object false A valid JSON object defining the update control map.
NOTE: Available only in the Enterprise plan.
enterprise
autogenerate_delta boolean false The flag idicating if the autogeneration of delta artifacts is enabled for a given deployment.

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 Plans
name string true Name of the deployment
artifact_name string true Name of the artifact to deploy
force_installation boolean false Force the installation of the Artifact disabling the already-installed check.
phases [NewDeploymentPhase] false [An array of deployments phases. Phases define a starting point and
a relative batch size of devices to which the deployment applies.

A single phase allows scheduling a deployment to start at a specific
time.

Multiple phases split the deployment into smaller batches of devices
at the time giving a higher level of control of the rate devices are
updated.

NOTE: Professional plan is only allowed to specify a single phase to
schedule deployments, this feature is not available for Starter plan.
]
professional, enterprise
retries integer false The number of times a device can retry the deployment in case of failure, defaults to 0
update_control_map object false A valid JSON object defining the update control map.
NOTE: Available only in the Enterprise plan.
enterprise
autogenerate_delta boolean false The flag idicating if the autogeneration of delta artifacts is enabled for a given deployment.

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
id string true Deployment identifier
name string true Name of the deployment
artifact_name string true Name of the artifact to deploy
created string(date-time) true Deployment's creation date and time
finished string(date-time) false Deployment's completion date and time
status string true Status of the deployment
device_count integer true Number of devices the deployment acted upon
artifacts [string] false An array of artifact's identifiers.
groups [string] false An array of groups the devices targeted by the deployment belong to.
Available only if the user created the deployment for a group or a single device (if the device was in a static group).
phases [DeploymentPhase] false
retries integer false The number of times a device can retry the deployment in case of failure, defaults to 0
update_control_map object false A valid JSON object defining the update control map.
NOTE: Available only in the Enterprise plan.
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
type string false
configuration string false A string containing a configuration object provided
with the deployment constructor.
autogenerate_delta boolean false The flag idicating if the autogeneration of delta artifacts is enabled for a given deployment.
statistics DeploymentStatistics false
Enumerated Values
Property Value
status scheduled
status pending
status inprogress
status finished
type configuration
type software

NewDeploymentPhase

{
  "start_ts": "2019-07-07T21:10:17.063493443Z",
  "batch_size": 5
}

An array of deployments phases. Phases define a starting point and a relative batch size of devices to which the deployment applies.

A single phase allows scheduling a deployment to start at a specific time.

Multiple phases split the deployment into smaller batches of devices at the time giving a higher level of control of the rate devices are updated.

NOTE: Professional plan is only allowed to specify a single phase to schedule deployments, this feature is not available for Starter plan.

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

{
  "status": {
    "success": 3,
    "pending": 1,
    "failure": 0,
    "downloading": 1,
    "installing": 2,
    "rebooting": 3,
    "noartifact": 0,
    "already-installed": 0,
    "aborted": 0,
    "pause_before_installing": 0,
    "pause_before_rebooting": 0,
    "pause_before_committing": 0
  },
  "total_size": 0
}

Properties
Name Type Required Description
status DeploymentStatusStatistics false
total_size integer false Sum of sizes (in bytes) of all artifacts assigned to all device deployments,
which are part of this deployment.
If the same artifact is assigned to multiple device deployments,
its size will be counted multiple times.

DeploymentStatusStatistics

{
  "success": 3,
  "pending": 1,
  "failure": 0,
  "downloading": 1,
  "installing": 2,
  "rebooting": 3,
  "noartifact": 0,
  "already-installed": 0,
  "aborted": 0,
  "pause_before_installing": 0,
  "pause_before_rebooting": 0,
  "pause_before_committing": 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.
pause_before_installing integer true Number of deployments paused before install state.
pause_before_rebooting integer true Number of deployments paused before reboot phase.
pause_before_committing integer true Number of deployments paused before commit phase.

Device

{
  "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
  "finished": "2016-03-11T13:03:17.063493443Z",
  "status": "installing",
  "created": "2016-02-11T13:03:17.063493443Z",
  "started": "2016-02-12T13: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.
status DeviceStatus true
created string(date-time) false
started string(date-time) false
finished string(date-time) false
deleted 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

DeviceWithImage

{
  "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
  "finished": "2016-03-11T13:03:17.063493443Z",
  "status": "installing",
  "created": "2016-02-11T13:03:17.063493443Z",
  "started": "2016-02-12T13:03:17.063493443Z",
  "device_type": "Raspberry Pi 3",
  "log": false,
  "state": "installing",
  "substate": "installing.enter;script:foo-bar",
  "image": {
    "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
    "name": "Application 1.0.0",
    "meta": {
      "description": "Johns Monday test build"
    },
    "meta_artifact": {
      "name": "Application 1.0.0",
      "device_types_compatible": [
        "Beagle Bone"
      ],
      "info": {
        "format": "mender",
        "version": 3
      },
      "signed": false,
      "updates": [
        {
          "type_info": {
            "type": "rootfs-image"
          },
          "files": [
            {
              "name": "rootfs-image-1",
              "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
              "size": 123,
              "date": "2016-03-11T13:03:17.063+0000"
            }
          ],
          "meta_data": {}
        }
      ],
      "artifact_provides": {
        "artifact_name": "test",
        "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
        "rootfs-image.version": "test"
      },
      "artifact_depends": {
        "device_type": [
          "test"
        ]
      },
      "clears_artifact_provides": [
        "rootfs-image.*"
      ]
    },
    "size": 36891648,
    "modified": "2016-03-11T13:03:17.063493443Z"
  }
}

Properties
Name Type Required Description
id string true Device identifier.
status DeviceStatus true
created string(date-time) false
started string(date-time) false
finished string(date-time) false
deleted 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
image object false
» id string false Image ID
» meta object false
»» description string false Image description
» meta_artifact object false
»» name string false
»» device_types_compatible [string] false An array of compatible device types.
»» info ArtifactInfo false Information about artifact format and version.
»» signed boolean false Idicates if artifact is signed or not.
»» updates [Update] false [Single updated to be applied.
]
»» artifact_provides object false List of Artifact provides.

Map of key/value pairs, where both keys and values are strings.
»»» additionalProperties string false
»» artifact_depends object false List of Artifact depends.

Map of key/value pairs, where keys are strings and values are lists of strings.
»»» additionalProperties [string] false
»» clears_artifact_provides [string] false List of Clear Artifact provides.
» size integer false Image size in bytes
» modified string(date-time) false Creation / last edition of any of the artifact properties

DeviceDeployment

{
  "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
  "deployment": {
    "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
    "name": "production",
    "artifact_name": "Application 0.0.1",
    "status": "inprogress",
    "created": "2016-02-11T13:03:17.063493443Z",
    "device_count": 100
  },
  "device": {
    "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
    "device_type": "Raspberry Pi 3",
    "status": "installing",
    "finished": "2016-03-11T13:03:17.063493443Z",
    "created": "2016-02-11T13:03:17.063493443Z",
    "started": "2016-02-11T13:03:17.063493443Z",
    "state": "installing",
    "substate": "installing.enter;script:foo-bar",
    "log": false,
    "image": {
      "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
      "name": "Application 1.0.0",
      "meta": {
        "description": "Johns Monday test build"
      },
      "meta_artifact": {
        "name": "Application 1.0.0",
        "device_types_compatible": [
          "Beagle Bone"
        ],
        "info": {
          "format": "mender",
          "version": 3
        },
        "signed": false,
        "updates": [
          {
            "type_info": {
              "type": "rootfs-image"
            },
            "files": [
              {
                "name": "rootfs-image-1",
                "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                "size": 123,
                "date": "2016-03-11T13:03:17.063+0000"
              }
            ],
            "meta_data": {}
          }
        ],
        "artifact_provides": {
          "artifact_name": "test",
          "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
          "rootfs-image.version": "test"
        },
        "artifact_depends": {
          "device_type": [
            "test"
          ]
        },
        "clears_artifact_provides": [
          "rootfs-image.*"
        ]
      },
      "size": 36891648,
      "modified": "2016-03-11T13:03:17.063493443Z"
    }
  }
}

Properties
Name Type Required Description
id string false
deployment Deployment true
device DeviceWithImage true

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 Note that for emtpy Artifacts, the type is 'null'

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

{
  "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
  "name": "Application 1.0.0",
  "description": "Johns Monday test build",
  "device_types_compatible": [
    "Beagle Bone"
  ],
  "info": {
    "format": "mender",
    "version": 3
  },
  "signed": false,
  "updates": [
    {
      "type_info": {
        "type": "rootfs-image"
      },
      "files": [
        {
          "name": "rootfs-image-1",
          "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
          "size": 123,
          "date": "2016-03-11T13:03:17.063+0000"
        }
      ],
      "meta_data": {}
    }
  ],
  "artifact_provides": {
    "artifact_name": "test",
    "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
    "rootfs-image.version": "test"
  },
  "artifact_depends": {
    "device_type": [
      "test"
    ]
  },
  "clears_artifact_provides": [
    "rootfs-image.*"
  ],
  "size": 36891648,
  "modified": "2016-03-11T13:03:17.063493443Z"
}

Detailed artifact.

Properties
Name Type Required Description
id string true
name string true
description string true
device_types_compatible [string] true An array of compatible device types.
info ArtifactInfo false Information about artifact format and version.
signed boolean false Idicates if artifact is signed or not.
updates [Update] false [Single updated to be applied.
]
artifact_provides object false List of Artifact provides.

Map of key/value pairs, where both keys and values are strings.
» additionalProperties string false
artifact_depends object false List of Artifact depends.

Map of key/value pairs, where keys are strings and values are lists of strings.
» additionalProperties [string] false
clears_artifact_provides [string] false List of Clear Artifact provides.
size number(integer) false Artifact total size in bytes - the size of the actual file that will be transferred to the device (compressed).
modified string(date-time) true Represents creation / last edition of any of the artifact properties.
{
  "uri": "http://mender.io/artifact.tar.gz.mender",
  "expire": "2016-10-29T10:45:34Z"
}

URL for artifact file download.

Properties
Name Type Required Description
uri string true
expire string(date-time) true
{
  "id": "07d2e773-a2a3-4f64-936a-4245e79194dd",
  "uri": "https://hosted-mender-artifacts.s3.amazonaws.com/1234/40df67c4-e5e9-4042-981a-f43adebd5b88?X-Amz-Date=20230401T000000Z&X-Amz-Expires=900&X-Amz-Signature=6d656e646572",
  "expire": "2023-04-01T00:15:00Z"
}

URL for artifact file upload.

Properties
Name Type Required Description
id string(uuid) true The ID of the artifact upload intent.
uri string true
expire string(date-time) true

DeviceStatus

"failure"

Properties
Name Type Required Description
anonymous string false
Enumerated Values
Property Value
anonymous failure
anonymous aborted
anonymous pause_before_installing
anonymous pause_before_committing
anonymous pause_before_rebooting
anonymous downloading
anonymous installing
anonymous rebooting
anonymous pending
anonymous success
anonymous noartifact
anonymous already-installed
anonymous decommissioned

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": [
      {
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "name": "Application 1.0.0",
        "description": "Johns Monday test build",
        "device_types_compatible": [
          "Beagle Bone"
        ],
        "info": {
          "format": "mender",
          "version": 3
        },
        "signed": false,
        "updates": [
          {
            "type_info": {
              "type": "rootfs-image"
            },
            "files": [
              {
                "name": "rootfs-image-1",
                "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                "size": 123,
                "date": "2016-03-11T13:03:17.063+0000"
              }
            ],
            "meta_data": {}
          }
        ],
        "artifact_provides": {
          "artifact_name": "test",
          "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
          "rootfs-image.version": "test"
        },
        "artifact_depends": {
          "device_type": [
            "test"
          ]
        },
        "clears_artifact_provides": [
          "rootfs-image.*"
        ],
        "size": 36891648,
        "modified": "2016-03-11T13:03:17.063493443Z"
      },
      {
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "name": "Application 1.0.0",
        "description": "Johns Monday test build",
        "device_types_compatible": [
          "Raspberry Pi"
        ],
        "info": {
          "format": "mender",
          "version": 3
        },
        "signed": false,
        "updates": [
          {
            "type_info": {
              "type": "rootfs-image"
            },
            "files": [
              {
                "name": "rootfs-image-1",
                "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                "size": 123,
                "date": "2016-03-11T13:03:17.063+0000"
              }
            ],
            "meta_data": {}
          }
        ],
        "artifact_provides": {
          "artifact_name": "test",
          "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
          "rootfs-image.version": "test"
        },
        "artifact_depends": {
          "device_type": [
            "test"
          ]
        },
        "clears_artifact_provides": [
          "rootfs-image.*"
        ],
        "size": 36891648,
        "modified": "2016-03-11T13:03:17.063493443Z"
      }
    ]
  }
]

List of releases

Properties
Name Type Required Description
anonymous [Release] false List of releases

Release

{
  "name": "my-app-v1.0.1",
  "artifacts": [
    {
      "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
      "name": "Application 1.0.0",
      "description": "Johns Monday test build",
      "device_types_compatible": [
        "Beagle Bone"
      ],
      "info": {
        "format": "mender",
        "version": 3
      },
      "signed": false,
      "updates": [
        {
          "type_info": {
            "type": "rootfs-image"
          },
          "files": [
            {
              "name": "rootfs-image-1",
              "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
              "size": 123,
              "date": "2016-03-11T13:03:17.063+0000"
            }
          ],
          "meta_data": {}
        }
      ],
      "artifact_provides": {
        "artifact_name": "test",
        "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
        "rootfs-image.version": "test"
      },
      "artifact_depends": {
        "device_type": [
          "test"
        ]
      },
      "clears_artifact_provides": [
        "rootfs-image.*"
      ],
      "size": 36891648,
      "modified": "2016-03-11T13:03:17.063493443Z"
    },
    {
      "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
      "name": "Application 1.0.0",
      "description": "Johns Monday test build",
      "device_types_compatible": [
        "Raspberry Pi"
      ],
      "info": {
        "format": "mender",
        "version": 3
      },
      "signed": false,
      "updates": [
        {
          "type_info": {
            "type": "rootfs-image"
          },
          "files": [
            {
              "name": "rootfs-image-1",
              "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
              "size": 123,
              "date": "2016-03-11T13:03:17.063+0000"
            }
          ],
          "meta_data": {}
        }
      ],
      "artifact_provides": {
        "artifact_name": "test",
        "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
        "rootfs-image.version": "test"
      },
      "artifact_depends": {
        "device_type": [
          "test"
        ]
      },
      "clears_artifact_provides": [
        "rootfs-image.*"
      ],
      "size": 36891648,
      "modified": "2016-03-11T13:03:17.063493443Z"
    }
  ]
}

Groups artifacts with the same release name into a single resource.

Properties
Name Type Required Description
name string false release name.
modified string(date-time) false Last modification time for the release.
artifacts [Artifact] false List of artifacts for this release.
tags [string] false Tags assigned to the release used for filtering releases. Each tag
must be valid a ASCII string and contain only lowercase and uppercase
letters, digits, underscores, periods and hyphens.
notes string false Additional information describing a Release limited to 1024 characters. Please use the v2 API to set this field.

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]

XDeltaArgs

{
  "disable_checksum": false,
  "disable_external_decompression": false,
  "compression_level": 6,
  "source_window_size": 0,
  "input_window_size": 0,
  "compression_duplicates_window": 0,
  "instruction_buffer_size": 0
}

xdelta3 arguments. Please refer to the xdelta3 documentation for a detailed description of the different options.

Properties
Name Type Required Description
disable_checksum boolean false Disables checksum
disable_external_decompression boolean false Disable external decompression
compression_level number(integer) false Compression level
source_window_size number(integer) false Source window size
input_window_size number(integer) false Input window size
compression_duplicates_window number(integer) false Compression duplicates window
instruction_buffer_size number(integer) false Instruction buffer size

XDeltaArgsLimits

{
  "compression_level": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "source_window_size": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "input_window_size": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "compression_duplicates_window": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "instruction_buffer_size": {
    "min": 5,
    "max": 100,
    "default": 10
  }
}

Limits for arguments which will be passed to xdelta3. Please refer to the xdelta3 documentation for a detailed description of the different options.

Properties
Name Type Required Description
compression_level Limit false Limit for compression level.
source_window_size Limit false Limit for source window size.
input_window_size Limit false Limit for input window size limit.
compression_duplicates_window Limit false Limit for compression duplicates window.
instruction_buffer_size Limit false Limit for instruction buffer size.

BinaryDeltaConfiguration

{
  "xdelta_args": {
    "disable_checksum": false,
    "disable_external_decompression": false,
    "compression_level": 6,
    "source_window_size": 0,
    "input_window_size": 0,
    "compression_duplicates_window": 0,
    "instruction_buffer_size": 0
  },
  "timeout": 0
}

The mender-binary-delta-generator configuration options.

Properties
Name Type Required Description
xdelta_args XDeltaArgs false xdelta3 arguments. Please refer to the xdelta3 documentation
for a detailed description of the different options.
timeout number(integer) false Delta generation job timeout in seconds.

BinaryDeltaLimits

{
  "xdelta_args_limits": {
    "compression_level": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "source_window_size": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "input_window_size": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "compression_duplicates_window": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "instruction_buffer_size": {
      "min": 5,
      "max": 100,
      "default": 10
    }
  },
  "timeout": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "jobs_in_parallel": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "queue_length": {
    "min": 5,
    "max": 100,
    "default": 10
  }
}

The mender-binary-delta-generator configuration limits.

Properties
Name Type Required Description
xdelta_args_limits XDeltaArgsLimits false Limits for arguments which will be passed to xdelta3.
Please refer to the xdelta3 documentation
for a detailed description of the different options.
timeout Limit false Limit descriptor.
jobs_in_parallel Limit false Maximum number of delta generation jobs which can be run in parallel.
queue_length Limit false Maximum number of queued delta generation jobs.

DeltaConfiguration

{
  "enabled": true,
  "binary_delta": {
    "xdelta_args": {
      "disable_checksum": false,
      "disable_external_decompression": false,
      "compression_level": 6,
      "source_window_size": 0,
      "input_window_size": 0,
      "compression_duplicates_window": 0,
      "instruction_buffer_size": 0
    },
    "timeout": 0
  },
  "binary_delta_limits": {
    "xdelta_args_limits": {
      "compression_level": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "source_window_size": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "input_window_size": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "compression_duplicates_window": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "instruction_buffer_size": {
        "min": 5,
        "max": 100,
        "default": 10
      }
    },
    "timeout": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "jobs_in_parallel": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "queue_length": {
      "min": 5,
      "max": 100,
      "default": 10
    }
  }
}

Delta configuration options.

Properties
Name Type Required Description
enabled boolean false
binary_delta BinaryDeltaConfiguration false The mender-binary-delta-generator configuration options.
binary_delta_limits BinaryDeltaLimits false The mender-binary-delta-generator configuration limits.

Configuration

{
  "delta": {
    "enabled": true,
    "binary_delta": {
      "xdelta_args": {
        "disable_checksum": false,
        "disable_external_decompression": false,
        "compression_level": 6,
        "source_window_size": 0,
        "input_window_size": 0,
        "compression_duplicates_window": 0,
        "instruction_buffer_size": 0
      },
      "timeout": 0
    },
    "binary_delta_limits": {
      "xdelta_args_limits": {
        "compression_level": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "source_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "input_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "compression_duplicates_window": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "instruction_buffer_size": {
          "min": 5,
          "max": 100,
          "default": 10
        }
      },
      "timeout": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "jobs_in_parallel": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "queue_length": {
        "min": 5,
        "max": 100,
        "default": 10
      }
    }
  }
}

Configuration.

Properties
Name Type Required Description
delta DeltaConfiguration false Delta configuration options.

Limit

{
  "min": 5,
  "max": 100,
  "default": 10
}

Limit descriptor.

Properties
Name Type Required Description
min number false Minimum value.
max number false Maximum value.
default number false Default value.

DirectUploadMetadata

{
  "size": 0,
  "updates": [
    {
      "type_info": {
        "type": "string"
      },
      "files": [
        {
          "name": "string",
          "checksum": "string",
          "size": 0,
          "date": "2019-08-24T14:15:22Z"
        }
      ],
      "meta_data": {}
    }
  ]
}

Artifact metadata

Properties
Name Type Required Description
size integer false wsize of the artifact file.
updates [Update] false List of updates for this artifact.

JobStatus

{
  "id": "string",
  "workflowName": "string",
  "inputParameters": [
    {
      "name": "key",
      "value": "parameter"
    }
  ],
  "status": "string",
  "results": [
    {
      "success": true,
      "cli": {
        "command": [
          "string"
        ],
        "output": "string",
        "error": "string",
        "exitCode": 0
      },
      "request": {
        "statusCode": 0,
        "body": "string"
      },
      "response": {
        "uri": "string",
        "method": "string",
        "headers": [
          "string"
        ],
        "body": "string"
      }
    }
  ]
}

Properties
Name Type Required Description
id string false
workflowName string false
inputParameters [InputParameter] false
status string false
results [TaskResult] false

InputParameter

{
  "name": "key",
  "value": "parameter"
}

Properties
Name Type Required Description
name string true
value string true

TaskResult

{
  "success": true,
  "cli": {
    "command": [
      "string"
    ],
    "output": "string",
    "error": "string",
    "exitCode": 0
  },
  "request": {
    "statusCode": 0,
    "body": "string"
  },
  "response": {
    "uri": "string",
    "method": "string",
    "headers": [
      "string"
    ],
    "body": "string"
  }
}

Properties
Name Type Required Description
success boolean false
cli TaskResultCLI false
request TaskResultHTTPRequest false
response TaskResultHTTPResponse false

TaskResultCLI

{
  "command": [
    "string"
  ],
  "output": "string",
  "error": "string",
  "exitCode": 0
}

Properties
Name Type Required Description
command [string] false
output string false
error string false
exitCode integer false

TaskResultHTTPRequest

{
  "statusCode": 0,
  "body": "string"
}

Properties
Name Type Required Description
statusCode integer false
body string false

TaskResultHTTPResponse

{
  "uri": "string",
  "method": "string",
  "headers": [
    "string"
  ],
  "body": "string"
}

Properties
Name Type Required Description
uri string false
method string false
headers [string] false
body string false

DeploymentIdentifier

{
  "deployment_ids": [
    "string"
  ]
}

Deployment identifier

Properties
Name Type Required Description
deployment_ids [string] false

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 UI.

Base URLs:

Create Deployment

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/deployments/deployments \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v2/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",
  "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':'Bearer {access-token}'
};

fetch('https://hosted.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' => 'Bearer {access-token}'
}

result = RestClient.post 'https://hosted.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': 'Bearer {access-token}'
}

r = requests.post('https://hosted.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' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.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://hosted.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{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.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 NewDeploymentV2 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
409 Conflict An active deployment with the same parameters already exists. 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.

List Releases with pagination

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/deployments/deployments/releases \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v2/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/v2/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{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v2/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 and sorting by name or last modification date.

Parameters

Name In Type Required Description
name query string false Release name filter.
tag query array[string] false Tag filter.
update_type query string false Update type filter.
page query number(integer) false Starting page.
per_page query number(integer) false Maximum number of results per page.
sort query string false Sort the release list by the specified field and direction.
Detailed descriptions

sort: Sort the release list by the specified field and direction.

Enumerated Values
Parameter Value
sort artifacts_count:asc
sort artifacts_count:desc
sort modified:asc
sort modified:desc
sort name:asc
sort name:desc
sort tags:asc
sort tags:desc

Example responses

Successful response.

[
  {
    "name": "my-app-v1.0.1",
    "artifacts": [
      {
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "name": "Application 1.0.0",
        "description": "Johns Monday test build",
        "device_types_compatible": [
          "Beagle Bone"
        ],
        "info": {
          "format": "mender",
          "version": 3
        },
        "signed": false,
        "updates": [
          {
            "type_info": {
              "type": "rootfs-image"
            },
            "files": [
              {
                "name": "rootfs-image-1",
                "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                "size": 123,
                "date": "2016-03-11T13:03:17.063+0000"
              }
            ],
            "meta_data": []
          }
        ],
        "artifact_provides": {
          "artifact_name": "test",
          "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
          "rootfs-image.version": "test"
        },
        "artifact_depends": {
          "device_type": [
            "test"
          ]
        },
        "clears_artifact_provides": [
          "rootfs-image.*"
        ],
        "size": 36891648,
        "modified": "2016-03-11T13:03:17.063493443Z"
      },
      {
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "name": "Application 1.0.0",
        "description": "Johns Monday test build",
        "device_types_compatible": [
          "Raspberry Pi"
        ],
        "info": {
          "format": "mender",
          "version": 3
        },
        "signed": false,
        "updates": [
          {
            "type_info": {
              "type": "rootfs-image"
            },
            "files": [
              {
                "name": "rootfs-image-1",
                "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                "size": 123,
                "date": "2016-03-11T13:03:17.063+0000"
              }
            ],
            "meta_data": []
          }
        ],
        "artifact_provides": {
          "artifact_name": "test",
          "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
          "rootfs-image.version": "test"
        },
        "artifact_depends": {
          "device_type": [
            "test"
          ]
        },
        "clears_artifact_provides": [
          "rootfs-image.*"
        ],
        "size": 36891648,
        "modified": "2016-03-11T13:03:17.063493443Z"
      }
    ]
  },
  {
    "name": "my-app-v2.0.0",
    "artifacts": [
      {
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "name": "Application 2.0.0",
        "description": "Johns Monday test build",
        "device_types_compatible": [
          "Beagle Bone"
        ],
        "info": {
          "format": "mender",
          "version": 3
        },
        "signed": false,
        "updates": [
          {
            "type_info": {
              "type": "rootfs-image"
            },
            "files": [
              {
                "name": "rootfs-image-1",
                "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                "size": 123,
                "date": "2016-03-11T13:03:17.063+0000"
              }
            ],
            "meta_data": []
          }
        ],
        "artifact_provides": {
          "artifact_name": "test",
          "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
          "rootfs-image.version": "test"
        },
        "artifact_depends": {
          "device_type": [
            "test"
          ]
        },
        "clears_artifact_provides": [
          "rootfs-image.*"
        ],
        "size": 36891648,
        "modified": "2016-03-11T13:03:17.063493443Z"
      }
    ]
  }
]

401 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. Releases
401 Unauthorized Unauthorized. Error
500 Internal Server Error Internal Server Error. Error
Response Headers
Status Header Type Format Description
200 Link string Standard header, we support 'first', 'next', and 'prev'.
200 X-Total-Count integer Total number of releases matching query.

Delete Releases

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v2/deployments/deployments/releases?name=string \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

DELETE https://hosted.mender.io/api/management/v2/deployments/deployments/releases?name=string HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/deployments/deployments/releases?name=string',
{
  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' => 'Bearer {access-token}'
}

result = RestClient.delete 'https://hosted.mender.io/api/management/v2/deployments/deployments/releases',
  params: {
  'name' => 'string'
}, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.delete('https://hosted.mender.io/api/management/v2/deployments/deployments/releases', params={
  'name': 'string'
}, headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('DELETE','https://hosted.mender.io/api/management/v2/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/v2/deployments/deployments/releases?name=string");
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{"Bearer {access-token}"},
    }

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

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

DELETE /deployments/releases

Delete the releases with given names

Deletes releases with names provided in the message body. Releases used by deployments in progress can not be deleted until deployment finishes.

Parameters

Name In Type Required Description
name query string true Name of the release to be deleted

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 Releases deleted successfully. None
400 Bad Request Bad request, see error message for details. Error
401 Unauthorized Unauthorized. Error
409 Conflict Conflict. ReleasesDeleteError
500 Internal Server Error Internal Server Error. Error

Update Release information

Code samples

# You can also use wget
curl -X PATCH https://hosted.mender.io/api/management/v2/deployments/deployments/releases/{release_name} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

PATCH https://hosted.mender.io/api/management/v2/deployments/deployments/releases/{release_name} HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "notes": "New security fixes 2023"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/deployments/deployments/releases/{release_name}',
{
  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' => 'Bearer {access-token}'
}

result = RestClient.patch 'https://hosted.mender.io/api/management/v2/deployments/deployments/releases/{release_name}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.patch('https://hosted.mender.io/api/management/v2/deployments/deployments/releases/{release_name}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('PATCH','https://hosted.mender.io/api/management/v2/deployments/deployments/releases/{release_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/v2/deployments/deployments/releases/{release_name}");
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{"Bearer {access-token}"},
    }

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

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

PATCH /deployments/releases/{release_name}

*Update selected fields of the Release object. *

Updates the Release object.

Body parameter

{
  "notes": "New security fixes 2023"
}

Parameters

Name In Type Required Description
release_name path string true Name of the release
body body ReleaseUpdate false

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 Successful response. None
400 Bad Request Bad request, see error message for details. Error
401 Unauthorized Unauthorized. Error
500 Internal Server Error Internal Server Error. Error

Assign Release Tags

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v2/deployments/deployments/releases/{release_name}/tags \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

PUT https://hosted.mender.io/api/management/v2/deployments/deployments/releases/{release_name}/tags 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':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/deployments/deployments/releases/{release_name}/tags',
{
  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' => 'Bearer {access-token}'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v2/deployments/deployments/releases/{release_name}/tags',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.put('https://hosted.mender.io/api/management/v2/deployments/deployments/releases/{release_name}/tags', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/management/v2/deployments/deployments/releases/{release_name}/tags', 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/deployments/deployments/releases/{release_name}/tags");
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{"Bearer {access-token}"},
    }

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

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

PUT /deployments/releases/{release_name}/tags

*Update and replace the tags of a release. *

Assigns tags to a release. The tags associated with the release will be replaced with the ones defined in the request body.

LIMITATIONS:

Body parameter

[
  "string"
]

Parameters

Name In Type Required Description
release_name path string true Name of the release
body body Tags false

Example responses

400 Response

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

Too many unique tag keys in use.

{
  "error": "the total number of unique tags has been exceeded",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content Successful response. None
400 Bad Request Bad request, see error message for details. Error
401 Unauthorized Unauthorized. Error
409 Conflict Too many unique tag keys in use. Error
500 Internal Server Error Internal Server Error. Error

List Release Tags

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/deployments/releases/all/tags \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v2/deployments/releases/all/tags HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/deployments/releases/all/tags',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://hosted.mender.io/api/management/v2/deployments/releases/all/tags', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v2/deployments/releases/all/tags', 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/deployments/releases/all/tags");
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{"Bearer {access-token}"},
    }

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

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

GET /releases/all/tags

*Lists all available tags for releases. *

Example responses

200 Response

[
  "string"
]

Too many unique tag keys in use.

{
  "error": "the total number of unique tags has been exceeded",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK Successful response. Tags
400 Bad Request Bad request, see error message for details. Error
401 Unauthorized Unauthorized. Error
409 Conflict Too many unique tag keys in use. Error
500 Internal Server Error Internal Server Error. Error

List Release Types

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/deployments/releases/all/types \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v2/deployments/releases/all/types HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/deployments/releases/all/types',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://hosted.mender.io/api/management/v2/deployments/releases/all/types', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v2/deployments/releases/all/types', 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/deployments/releases/all/types");
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{"Bearer {access-token}"},
    }

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

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

GET /releases/all/types

*Lists all release update types. *

Example responses

200 Response

[
  "string"
]

Responses

Status Meaning Description Schema
200 OK Successful response. UpdateTypes
400 Bad Request Bad request, see error message for details. Error
401 Unauthorized Unauthorized. Error
500 Internal Server Error Internal Server Error. Error

Schemas

Artifact

{
  "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
  "name": "Application 1.0.0",
  "description": "Johns Monday test build",
  "device_types_compatible": [
    "Beagle Bone"
  ],
  "info": {
    "format": "mender",
    "version": 3
  },
  "signed": false,
  "updates": [
    {
      "type_info": {
        "type": "rootfs-image"
      },
      "files": [
        {
          "name": "rootfs-image-1",
          "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
          "size": 123,
          "date": "2016-03-11T13:03:17.063+0000"
        }
      ],
      "meta_data": []
    }
  ],
  "artifact_provides": {
    "artifact_name": "test",
    "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
    "rootfs-image.version": "test"
  },
  "artifact_depends": {
    "device_type": [
      "test"
    ]
  },
  "clears_artifact_provides": [
    "rootfs-image.*"
  ],
  "size": 36891648,
  "modified": "2016-03-11T13:03:17.063493443Z"
}

Detailed artifact.

Properties
Name Type Required Description
id string true
name string true
description string true
device_types_compatible [string] true An array of compatible device types.
info ArtifactInfo false Information about artifact format and version.
signed boolean false Idicates if artifact is signed or not.
updates [Update] false [Single updated to be applied.
]
artifact_provides object false List of Artifact provides.

Map of key/value pairs, where both keys and values are strings.
» additionalProperties string false
artifact_depends object false List of Artifact depends.

Map of key/value pairs, where keys are strings and values are lists of strings.
» additionalProperties [string] false
clears_artifact_provides [string] false List of Clear Artifact provides.
size number(integer) false Artifact total size in bytes - the size of the actual file that will be transferred to the device (compressed).
modified string(date-time) true Represents creation / last edition of any of the artifact properties.

ArtifactInfo

{
  "format": "string",
  "version": 0
}

Information about artifact format and version.

Properties
Name Type Required Description
format string false
version integer false

ArtifactTypeInfo

{
  "type": "string"
}

Information about update type.

Properties
Name Type Required Description
type string false Note that for emtpy Artifacts, the type is 'null'

Releases

[
  {
    "name": "my-app-v1.0.1",
    "artifacts": [
      {
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "name": "Application 1.0.0",
        "description": "Johns Monday test build",
        "device_types_compatible": [
          "Beagle Bone"
        ],
        "info": {
          "format": "mender",
          "version": 3
        },
        "signed": false,
        "updates": [
          {
            "type_info": {
              "type": "rootfs-image"
            },
            "files": [
              {
                "name": "rootfs-image-1",
                "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                "size": 123,
                "date": "2016-03-11T13:03:17.063+0000"
              }
            ],
            "meta_data": []
          }
        ],
        "artifact_provides": {
          "artifact_name": "test",
          "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
          "rootfs-image.version": "test"
        },
        "artifact_depends": {
          "device_type": [
            "test"
          ]
        },
        "clears_artifact_provides": [
          "rootfs-image.*"
        ],
        "size": 36891648,
        "modified": "2016-03-11T13:03:17.063493443Z"
      },
      {
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "name": "Application 1.0.0",
        "description": "Johns Monday test build",
        "device_types_compatible": [
          "Raspberry Pi"
        ],
        "info": {
          "format": "mender",
          "version": 3
        },
        "signed": false,
        "updates": [
          {
            "type_info": {
              "type": "rootfs-image"
            },
            "files": [
              {
                "name": "rootfs-image-1",
                "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                "size": 123,
                "date": "2016-03-11T13:03:17.063+0000"
              }
            ],
            "meta_data": []
          }
        ],
        "artifact_provides": {
          "artifact_name": "test",
          "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
          "rootfs-image.version": "test"
        },
        "artifact_depends": {
          "device_type": [
            "test"
          ]
        },
        "clears_artifact_provides": [
          "rootfs-image.*"
        ],
        "size": 36891648,
        "modified": "2016-03-11T13:03:17.063493443Z"
      }
    ]
  }
]

List of releases

Properties
Name Type Required Description
anonymous [Release] false List of releases

Release

{
  "name": "my-app-v1.0.1",
  "artifacts": [
    {
      "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
      "name": "Application 1.0.0",
      "description": "Johns Monday test build",
      "device_types_compatible": [
        "Beagle Bone"
      ],
      "info": {
        "format": "mender",
        "version": 3
      },
      "signed": false,
      "updates": [
        {
          "type_info": {
            "type": "rootfs-image"
          },
          "files": [
            {
              "name": "rootfs-image-1",
              "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
              "size": 123,
              "date": "2016-03-11T13:03:17.063+0000"
            }
          ],
          "meta_data": []
        }
      ],
      "artifact_provides": {
        "artifact_name": "test",
        "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
        "rootfs-image.version": "test"
      },
      "artifact_depends": {
        "device_type": [
          "test"
        ]
      },
      "clears_artifact_provides": [
        "rootfs-image.*"
      ],
      "size": 36891648,
      "modified": "2016-03-11T13:03:17.063493443Z"
    },
    {
      "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
      "name": "Application 1.0.0",
      "description": "Johns Monday test build",
      "device_types_compatible": [
        "Raspberry Pi"
      ],
      "info": {
        "format": "mender",
        "version": 3
      },
      "signed": false,
      "updates": [
        {
          "type_info": {
            "type": "rootfs-image"
          },
          "files": [
            {
              "name": "rootfs-image-1",
              "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
              "size": 123,
              "date": "2016-03-11T13:03:17.063+0000"
            }
          ],
          "meta_data": []
        }
      ],
      "artifact_provides": {
        "artifact_name": "test",
        "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
        "rootfs-image.version": "test"
      },
      "artifact_depends": {
        "device_type": [
          "test"
        ]
      },
      "clears_artifact_provides": [
        "rootfs-image.*"
      ],
      "size": 36891648,
      "modified": "2016-03-11T13:03:17.063493443Z"
    }
  ]
}

Groups artifacts with the same release name into a single resource.

Properties
Name Type Required Description
name string false release name.
modified string(date-time) false Last modification time for the release.
artifacts [Artifact] false List of artifacts for this release.
tags [string] false Tags assigned to the release used for filtering releases. Each tag
must be valid a ASCII string and contain only lowercase and uppercase
letters, digits, underscores, periods and hyphens.
notes string false Additional information describing a Release limited to 1024 characters. Please use the v2 API to set this field.

ReleaseUpdate

{
  "notes": "New security fixes 2023"
}

Fields to be updated in the given Release.

Properties
Name Type Required Description
notes string false Release notes, limited to maximum length.

Tags

[
  "string"
]

Tags assigned to the release used for filtering releases. Each tag must be valid a ASCII string and contain only lowercase and uppercase letters, digits, underscores, periods and hyphens.

Properties

None

Update

{
  "type_info": {
    "type": "string"
  },
  "files": [
    {
      "name": "string",
      "checksum": "string",
      "size": 0,
      "date": "2019-08-24T14:15:22Z"
    }
  ],
  "meta_data": [
    null
  ]
}

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 [any] false meta_data is an array of objects of unknown structure as this
is dependent of update type (also custom defined by user)

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

UpdateTypes

[
  "string"
]

Update types as present in the images.

Properties

None

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).

NewDeploymentV2

{
  "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 Plans
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
update_control_map object false A valid JSON object defining the update control map.
NOTE: Available only in the Enterprise plan.
enterprise
autogenerate_delta boolean false The flag idicating if the autogeneration of delta artifacts is enabled for a given deployment.

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').

ReleasesDeleteError

{
  "error": "active deployments are using some of the releases from the request",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Releases used by active deployment.

Properties
Name Type Required Description
error string false Description of the error.
active_deployments [string] false List of IDs of active deployments which are using releases from the request.
request_id string false Request ID (same as in X-MEN-RequestID header).

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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.
id query array[string] false Device ID filter. Can be repeated to query a set of devices.
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",
    "check_in_time": "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",
        "device_id": "string"
      }
    ],
    "decommissioning": true,
    "external_id": {
      "data": "iot-hub device-id/module-id",
      "active": 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
» check_in_time string(date-time) false Time when accepted device contacted server for the last time.
» 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
»» device_id string false Device ID connected to authentication data set
» decommissioning boolean false Devices that are part of ongoing decommissioning process will return True
» external_id ExternalIdentity false Device external identity.
»» data string false External identity.
»» active boolean false Status flag.
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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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 device.

Search Devices

Code samples

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

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

const inputBody = '{
  "status": "pending",
  "id": [
    "string"
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/devauth/devices/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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

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

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/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/devauth/devices/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{"Bearer {access-token}"},
    }

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

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

POST /devices/search

Query for devices. Returns a list of matching devices with AuthSets sorted by age.

Body parameter

{
  "status": "pending",
  "id": [
    "string"
  ]
}

Parameters

Name In Type Required Description
page query integer false Results page number
per_page query integer false Maximum number of results per page.
body body object true Device status filter.
» status body string false Device status filter. Can be an array for querying devices from multiple device statuses.
» id body [string] false Device ID filter. Can be a string for querying for a single device.
Detailed descriptions

body: Device status filter. All properties can be either a single string or an array of strings.

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",
    "check_in_time": "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",
        "device_id": "string"
      }
    ],
    "decommissioning": true,
    "external_id": {
      "data": "iot-hub device-id/module-id",
      "active": true
    }
  }
]

Responses

Status Meaning Description Schema
200 OK Successful response Inline
400 Bad Request Missing/malformed request params. Error
500 Internal Server Error Unexpected error Error
Response Schema

Status Code 200

Array of devices

Name Type Required Restrictions Description
anonymous [Device] false Array of devices
» 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
» check_in_time string(date-time) false Time when accepted device contacted server for the last time.
» 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
»» device_id string false Device ID connected to authentication data set
» decommissioning boolean false Devices that are part of ongoing decommissioning process will return True
» external_id ExternalIdentity false Device external identity.
»» data string false External identity.
»» active boolean false Status flag.
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 Pagination link header, we support 'first', 'next', and 'prev'.

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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",
  "check_in_time": "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",
      "device_id": "string"
    }
  ],
  "decommissioning": true,
  "external_id": {
    "data": "iot-hub device-id/module-id",
    "active": 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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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

Get Device License

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/devauth/license \
  -H 'Accept: text/csv' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v2/devauth/license HTTP/1.1
Host: hosted.mender.io
Accept: text/csv


const headers = {
  'Accept':'text/csv',
  'Authorization':'Bearer {access-token}'
};

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

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'text/csv',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'text/csv',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'text/csv',
    'Authorization' => 'Bearer {access-token}',
);

$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/license', 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/license");
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{"text/csv"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

GET /license

Obtain license information for devices.

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK Usage statistics and limits. string
404 Not Found The license data could not be found. Error

Automatically Authenticate Device

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/devauth/auto-auth \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-MEN-Signature: string' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v2/devauth/auto-auth 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':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/devauth/auto-auth',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

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

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'X-MEN-Signature' => 'string',
    'Authorization' => 'Bearer {access-token}',
);

$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/auto-auth', 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/auto-auth");
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{"Bearer {access-token}"},
    }

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

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

POST /auto-auth

Automatically accept a device

The caller presents device identity data and public key, and signs the request with a private key. If the request is valid the device is accepted, and a valid JWT authentication token is issued.

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 AutoAuthRequest 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

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",
  "check_in_time": "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",
      "device_id": "string"
    }
  ],
  "decommissioning": true,
  "external_id": {
    "data": "iot-hub device-id/module-id",
    "active": 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
check_in_time string(date-time) false Time when accepted device contacted server for the last time.
auth_sets [AuthSet] false [Authentication data set]
decommissioning boolean false Devices that are part of ongoing decommissioning process will return True
external_id ExternalIdentity false Device external identity.
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",
  "device_id": "string"
}

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
device_id string false Device ID connected to authentication data set
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
force boolean false Indicates that despite the device having any authsets the preauthorization should proceed.
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.

ExternalIdentity

{
  "data": "iot-hub device-id/module-id",
  "active": true
}

Device external identity.

Properties
Name Type Required Description
data string false External identity.
active boolean false Status flag.

AutoAuthRequest

{
  "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.
external_id string false External identity which can be used to verify devices managed by cloud providers.
Currently, only Azure IoT Edge devices are supported.

Device configure

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

API for managing device configuration. Intended for use by the web GUI

Base URLs:

Get Device Configuration

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId}',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId}', 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/deviceconfig/configurations/device/{deviceId}");
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{"Bearer {access-token}"},
    }

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

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

GET /configurations/device/{deviceId}

Get the device's configuration

Parameters

Name In Type Required Description
deviceId path string(uuid) true ID of the device to query.

Example responses

200 Response

{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "configured": {
    "property1": "string",
    "property2": "string"
  },
  "reported": {
    "property1": "string",
    "property2": "string"
  },
  "deployment_id": "6ef0ac85-9892-4664-a2a5-58bf2af5a8a6",
  "reported_ts": "2019-08-24T14:15:22Z",
  "updated_ts": "2019-08-24T14:15:22Z"
}

Responses

Status Meaning Description Schema
200 OK Success DeviceConfiguration
400 Bad Request Bad Request. Error
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

Set Device Configuration

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

PUT https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId} HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "property1": "string",
  "property2": "string"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId}',
{
  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' => 'Bearer {access-token}'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.put('https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId}', 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/deviceconfig/configurations/device/{deviceId}");
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{"Bearer {access-token}"},
    }

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

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

PUT /configurations/device/{deviceId}

Set the device's configuration

Body parameter

{
  "property1": "string",
  "property2": "string"
}

Parameters

Name In Type Required Description
deviceId path string true ID of the device to query.
body body ManagementAPIConfiguration false

Example responses

400 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content Success None
400 Bad Request Bad Request. Error
500 Internal Server Error Internal Server Error. Error

Deploy Device Configuration

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId}/deploy \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId}/deploy HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "retries": 0,
  "update_control_map": {}
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId}/deploy',
{
  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' => 'Bearer {access-token}'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId}/deploy',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId}/deploy', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId}/deploy', 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/deviceconfig/configurations/device/{deviceId}/deploy");
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{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v1/deviceconfig/configurations/device/{deviceId}/deploy", data)
    req.Header = headers

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

POST /configurations/device/{deviceId}/deploy

Deploy the device's configuration

Body parameter

{
  "retries": 0,
  "update_control_map": {}
}

Parameters

Name In Type Required Description
deviceId path string true ID of the device.
body body NewConfigurationDeployment true

Example responses

200 Response

{
  "deployment_id": "string"
}

Responses

Status Meaning Description Schema
200 OK Success NewConfigurationDeploymentResponse
400 Bad Request Bad Request. Error
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

Schemas

ManagementAPIConfiguration

{
  "property1": "string",
  "property2": "string"
}

Properties
Name Type Required Description
additionalProperties string false

NewConfigurationDeployment

{
  "retries": 0,
  "update_control_map": {}
}

Properties
Name Type Required Description Plans
retries integer false The number of times a device can retry the deployment in case of failure, defaults to 0
update_control_map object false A valid JSON object defining the update control map.
NOTE: Available only in the Enterprise plan.
enterprise

NewConfigurationDeploymentResponse

{
  "deployment_id": "string"
}

Properties
Name Type Required Description
deployment_id string false Deployment ID

DeviceConfiguration

{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "configured": {
    "property1": "string",
    "property2": "string"
  },
  "reported": {
    "property1": "string",
    "property2": "string"
  },
  "deployment_id": "6ef0ac85-9892-4664-a2a5-58bf2af5a8a6",
  "reported_ts": "2019-08-24T14:15:22Z",
  "updated_ts": "2019-08-24T14:15:22Z"
}

Properties
Name Type Required Description
id string(uuid) false
configured ManagementAPIConfiguration false
reported ManagementAPIConfiguration false
deployment_id string(uuid) false ID of the latest configuration deployment
reported_ts string(date-time) false
updated_ts string(date-time) false

Error

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.
request_id string false Request ID passed with the request X-Men-Requestid header or generated by the server.

Device connect

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

API for managing persistent device connections. Intended for use by the web GUI

Base URLs:

Get device

Code samples

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

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deviceconnect/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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/deviceconnect/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/deviceconnect/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{"Bearer {access-token}"},
    }

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

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

GET /devices/{id}

Fetch the state of a device.

Parameters

Name In Type Required Description
id path string(uuid) true ID of the device.

Example responses

200 Response

{
  "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940",
  "status": "connected",
  "updated_ts": "2019-08-24T14:15:22Z",
  "created_ts": "2019-08-24T14:15:22Z"
}

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

404 Response

{
  "error": "Device not found",
  "request_id": "eed14d55-d996-42cd-8248-e806663810aa"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
200 OK Successful response. DeviceState
400 Bad Request Invalid Request. Error
404 Not Found Device not found. Error
500 Internal Server Error Internal Server Error. Error

Check Update

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/check-update \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/check-update HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/check-update',
{
  method: 'POST',

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/check-update',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/check-update', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/check-update', 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/deviceconnect/devices/{id}/check-update");
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{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

POST /devices/{id}/check-update

Trigger check-update for the Mender client running on the device

Parameters

Name In Type Required Description
id path string(uuid) true ID of the device.

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

404 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
202 Accepted Accepted None
400 Bad Request Invalid Request. Error
404 Not Found Device not found. Error
409 Conflict Device not connected. Error
500 Internal Server Error Internal Server Error. Error

Connect

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/connect \
  -H 'Accept: application/json' \
  -H 'Connection: Upgrade' \
  -H 'Upgrade: websocket' \
  -H 'Sec-Websocket-Key: string' \
  -H 'Sec-Websocket-Version: 13' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/connect HTTP/1.1
Host: hosted.mender.io
Accept: application/json
Connection: Upgrade
Upgrade: websocket
Sec-Websocket-Key: string
Sec-Websocket-Version: 13


const headers = {
  'Accept':'application/json',
  'Connection':'Upgrade',
  'Upgrade':'websocket',
  'Sec-Websocket-Key':'string',
  'Sec-Websocket-Version':'13',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/connect',
{
  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',
  'Connection' => 'Upgrade',
  'Upgrade' => 'websocket',
  'Sec-Websocket-Key' => 'string',
  'Sec-Websocket-Version' => '13',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Connection': 'Upgrade',
  'Upgrade': 'websocket',
  'Sec-Websocket-Key': 'string',
  'Sec-Websocket-Version': '13',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Connection' => 'Upgrade',
    'Upgrade' => 'websocket',
    'Sec-Websocket-Key' => 'string',
    'Sec-Websocket-Version' => '13',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/connect', 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/deviceconnect/devices/{id}/connect");
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"},
        "Connection": []string{"Upgrade"},
        "Upgrade": []string{"websocket"},
        "Sec-Websocket-Key": []string{"string"},
        "Sec-Websocket-Version": []string{"13"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

GET /devices/{id}/connect

Establish permanent connection with device

Parameters

Name In Type Required Description
id path string(uuid) true ID of the device.
Connection header string false Standard websocket request header.
Upgrade header string(base64) false Standard websocket request header.
Sec-Websocket-Key header string(base64) false Standard websocket request header.
Sec-Websocket-Version header integer false Standard websocket request header.
Enumerated Values
Parameter Value
Connection Upgrade
Upgrade websocket
Sec-Websocket-Version 13

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

404 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
101 Switching Protocols Successful response - change to websocket protocol. None
400 Bad Request Invalid Request. Error
404 Not Found Device not found. Error
500 Internal Server Error Internal Server Error. Error

Download

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/download?path=string \
  -H 'Accept: application/octet-stream' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/download?path=string HTTP/1.1
Host: hosted.mender.io
Accept: application/octet-stream


const headers = {
  'Accept':'application/octet-stream',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/download?path=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/octet-stream',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/download',
  params: {
  'path' => 'string'
}, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/octet-stream',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/download', params={
  'path': 'string'
}, headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/octet-stream',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/deviceconnect/devices/{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/deviceconnect/devices/{id}/download?path=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/octet-stream"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

GET /devices/{id}/download

Download a file from the device

Parameters

Name In Type Required Description
id path string(uuid) true ID of the device.
path query string true Path of the file on the device.

Example responses

200 Response

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

404 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
200 OK The content of the file will be returned in the response body string
400 Bad Request Invalid Request. Error
404 Not Found Device not found. Error
409 Conflict Device not connected. Error
500 Internal Server Error Internal Server Error. Error
Response Headers
Status Header Type Format Description
200 X-MEN-File-Path string The path of the file on the device
200 X-MEN-File-UID integer The numerical UID of the file on the device
200 X-MEN-File-GID integer The numerical GID of the file on the device
200 X-MEN-File-Mode string The octal representation of the mode of the file on the device
200 X-MEN-File-Size integer The size of the file on the device

Send Inventory

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/send-inventory \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

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

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/send-inventory', 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/deviceconnect/devices/{id}/send-inventory");
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{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

POST /devices/{id}/send-inventory

Trigger send-inventory for the Mender client running on the device

Parameters

Name In Type Required Description
id path string(uuid) true ID of the device.

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

404 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
202 Accepted Accepted None
400 Bad Request Invalid Request. Error
404 Not Found Device not found. Error
409 Conflict Device not connected. Error
500 Internal Server Error Internal Server Error. Error

Playback

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deviceconnect/sessions/{session_id}/playback \
  -H 'Accept: application/json' \
  -H 'Connection: Upgrade' \
  -H 'Upgrade: websocket' \
  -H 'Sec-Websocket-Key: string' \
  -H 'Sec-Websocket-Version: 13' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v1/deviceconnect/sessions/{session_id}/playback HTTP/1.1
Host: hosted.mender.io
Accept: application/json
Connection: Upgrade
Upgrade: websocket
Sec-Websocket-Key: string
Sec-Websocket-Version: 13


const headers = {
  'Accept':'application/json',
  'Connection':'Upgrade',
  'Upgrade':'websocket',
  'Sec-Websocket-Key':'string',
  'Sec-Websocket-Version':'13',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deviceconnect/sessions/{session_id}/playback',
{
  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',
  'Connection' => 'Upgrade',
  'Upgrade' => 'websocket',
  'Sec-Websocket-Key' => 'string',
  'Sec-Websocket-Version' => '13',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Connection': 'Upgrade',
  'Upgrade': 'websocket',
  'Sec-Websocket-Key': 'string',
  'Sec-Websocket-Version': '13',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://hosted.mender.io/api/management/v1/deviceconnect/sessions/{session_id}/playback', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Connection' => 'Upgrade',
    'Upgrade' => 'websocket',
    'Sec-Websocket-Key' => 'string',
    'Sec-Websocket-Version' => '13',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/deviceconnect/sessions/{session_id}/playback', 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/deviceconnect/sessions/{session_id}/playback");
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"},
        "Connection": []string{"Upgrade"},
        "Upgrade": []string{"websocket"},
        "Sec-Websocket-Key": []string{"string"},
        "Sec-Websocket-Version": []string{"13"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

GET /sessions/{session_id}/playback

Establish a connection for playing back a session

Parameters

Name In Type Required Description
session_id path string true ID for the session to play back.
sleep_ms query integer false Time in millisconds to sleep between the subsequent playback data writes.
Connection header string false Standard websocket request header.
Upgrade header string(base64) false Standard websocket request header.
Sec-Websocket-Key header string(base64) false Standard websocket request header.
Sec-Websocket-Version header integer false Standard websocket request header.
Enumerated Values
Parameter Value
Connection Upgrade
Upgrade websocket
Sec-Websocket-Version 13

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

404 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
101 Switching Protocols Successful response - change to websocket protocol. None
400 Bad Request Invalid Request. Error
404 Not Found Session not found. Error
500 Internal Server Error Internal Server Error. Error

Upload

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/upload \
  -H 'Content-Type: multipart/form-data' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

PUT https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/upload HTTP/1.1
Host: hosted.mender.io
Content-Type: multipart/form-data
Accept: application/json

const inputBody = '{
  "path": "string",
  "uid": 0,
  "gid": 0,
  "mode": "string",
  "file": "string"
}';
const headers = {
  'Content-Type':'multipart/form-data',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/upload',
{
  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' => 'multipart/form-data',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'multipart/form-data',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'multipart/form-data',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/management/v1/deviceconnect/devices/{id}/upload', 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/deviceconnect/devices/{id}/upload");
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{"multipart/form-data"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

PUT /devices/{id}/upload

Upload a file to the device

Body parameter

path: string
uid: 0
gid: 0
mode: string
file: string

Parameters

Name In Type Required Description
id path string(uuid) true ID of the device.
body body FileUpload false

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

404 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
201 Created The file was successfully uploaded None
400 Bad Request Invalid Request. Error
404 Not Found Device not found. Error
409 Conflict Device not connected. Error
500 Internal Server Error Internal Server Error. Error

Schemas

DeviceState

{
  "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940",
  "status": "connected",
  "updated_ts": "2019-08-24T14:15:22Z",
  "created_ts": "2019-08-24T14:15:22Z"
}

Properties
Name Type Required Description
device_id string(uuid) false Device ID.
status string false Device status.
updated_ts string(date-time) false Server-side timestamp of the last device information update.
created_ts string(date-time) false Server-side timestamp of the device creation.
Enumerated Values
Property Value
status connected
status disconnected
status unknown

Error

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.
request_id string false Request ID passed with the request X-MEN-RequestID header or generated by the server.

FileUpload

{
  "path": "string",
  "uid": 0,
  "gid": 0,
  "mode": "string",
  "file": "string"
}

Properties
Name Type Required Description
path string true The destination path on the device
uid integer false The numerical UID of the file on the device
gid integer false The numerical GID of the file on the device
mode string false The octal representation of the mode of the file on the device
file string(binary) false

Device monitor

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

User-facing API for monitoring.

Base URLs:

List Alerts

Code samples

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

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/devicemonitor/devices/{id}/alerts',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/devicemonitor/devices/{id}/alerts', 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/devicemonitor/devices/{id}/alerts");
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{"Bearer {access-token}"},
    }

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

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

GET /devices/{id}/alerts

List the alerts for the given device.

Parameters

Name In Type Required Description
id path string true Device ID.
page query integer false The requested page number.
per_page query integer false The number of items per page.
issued_before query string(date-time) false Filter alerts issued before timestamp.
issued_after query string(date-time) false Filter alerts issued after timestamp.
sort_ascending query string false Filter by ascending timestamp (reverse).
Enumerated Values
Parameter Value
sort_ascending true
sort_ascending false

Example responses

200 Response

[
  {
    "name": "mender-connect systemd service",
    "level": "CRITICAL",
    "timestamp": "2019-07-21T17:32:28Z",
    "subject": {
      "name": "mender-connect",
      "status": "not-running",
      "type": "systemd.unit",
      "details": {
        "description": "Description of an error.",
        "lines_before": [
          {
            "line_number": 1,
            "data": "Line 1 from a log file"
          },
          {
            "line_number": 2,
            "data": "Line 2 from a log file"
          }
        ],
        "line_matching": {
          "line_number": 3,
          "data": "Line 3 from a log file"
        },
        "lines_after": [
          {
            "line_number": 4,
            "data": "Line 4 from a log file"
          },
          {
            "line_number": 5,
            "data": "Line 5 from a log file"
          }
        ]
      }
    }
  }
]

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
200 OK OK Inline
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error
Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [Alert] false
» id string(uuid) false A unique ID for the alert.
» name string false The name of the alert.
» device_id string true
» level string false Alert severity level
» subject AlertSubject true Alert subject: the description of the alert origin
»» name string true Name of an entity that caused the alert
»» type string true The type of executable that triggered the alert
»» status string true Status of an entity that caused the alert
»» details AlertDetails false Additional details on the alert.
»»» description string false Alert description.
»»» lines_before [LineDescriptor] false Log lines before matched pattern.
»»»» line_number integer true
»»»» data string true
»»» lines_after [LineDescriptor] false Log lines after matched pattern.
»»» line_matching LineDescriptor false Describes the data and line of a pattern-matched log line.
» timestamp string(date-time) true Time and date when the alert occurred
Enumerated Values
Property Value
level OK
level CRITICAL
Response Headers
Status Header Type Format Description
200 X-Total-Count integer The total number of alerts matching the query

List latest alerts

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/devicemonitor/devices/{id}/alerts/latest \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/devicemonitor/devices/{id}/alerts/latest',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/devicemonitor/devices/{id}/alerts/latest', 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/devicemonitor/devices/{id}/alerts/latest");
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{"Bearer {access-token}"},
    }

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

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

GET /devices/{id}/alerts/latest

List the latest alerts for the given device. An optional 'level_from' parameter filters the result by returning alerts with at least 'level_from' or higher severity level.

Parameters

Name In Type Required Description
id path string true Device ID.
level_from query string false Filter the result by having level_from or higher severity level.
issued_before query string(date-time) false Only show alerts older than issued_before.
issued_after query string(date-time) false Only show alerts older than issued_after.
page query integer false The requested page number.
per_page query integer false The number of items per page.
Enumerated Values
Parameter Value
level_from OK
level_from CRITICAL

Example responses

200 Response

[
  {
    "name": "mender-connect systemd service",
    "level": "CRITICAL",
    "timestamp": "2019-07-21T17:32:28Z",
    "subject": {
      "name": "mender-connect",
      "status": "not-running",
      "type": "systemd.unit",
      "details": {
        "description": "Description of an error.",
        "lines_before": [
          {
            "line_number": 1,
            "data": "Line 1 from a log file"
          },
          {
            "line_number": 2,
            "data": "Line 2 from a log file"
          }
        ],
        "line_matching": {
          "line_number": 3,
          "data": "Line 3 from a log file"
        },
        "lines_after": [
          {
            "line_number": 4,
            "data": "Line 4 from a log file"
          },
          {
            "line_number": 5,
            "data": "Line 5 from a log file"
          }
        ]
      }
    }
  }
]

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
200 OK OK.
Lists latest alerts sorted by oldest alert first. Inline
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error
Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [Alert] false
» id string(uuid) false A unique ID for the alert.
» name string false The name of the alert.
» device_id string true
» level string false Alert severity level
» subject AlertSubject true Alert subject: the description of the alert origin
»» name string true Name of an entity that caused the alert
»» type string true The type of executable that triggered the alert
»» status string true Status of an entity that caused the alert
»» details AlertDetails false Additional details on the alert.
»»» description string false Alert description.
»»» lines_before [LineDescriptor] false Log lines before matched pattern.
»»»» line_number integer true
»»»» data string true
»»» lines_after [LineDescriptor] false Log lines after matched pattern.
»»» line_matching LineDescriptor false Describes the data and line of a pattern-matched log line.
» timestamp string(date-time) true Time and date when the alert occurred
Enumerated Values
Property Value
level OK
level CRITICAL

Monitor Checks Configuration

Code samples

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

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/devicemonitor/devices/{id}/config',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/devicemonitor/devices/{id}/config', 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/devicemonitor/devices/{id}/config");
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{"Bearer {access-token}"},
    }

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

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

GET /devices/{id}/config

List the check configured on a device.

Parameters

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

Example responses

200 Response

[
  {
    "name": "string",
    "status": "string",
    "type": "log",
    "log": {
      "pattern": "string",
      "path": "string",
      "expire_seconds": 0
    }
  }
]

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
200 OK OK Inline
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error
Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [allOf] false [Monitor configuration data.
]

allOf

Name Type Required Restrictions Description
» anonymous object false
»» name string true
»» status string true
»» type string true

and - discriminator: type

Name Type Required Restrictions Description
» anonymous any false

oneOf

Name Type Required Restrictions Description
»» anonymous LogSubsystem false log subsystem specific configuration
»»» log object true
»»»» pattern string true Log pattern
»»»» path string true Path to the log file or command to execute to get the logs (prefixed with '@').
»»»» expire_seconds integer false Number of seconds after which the pattern is considered expired and an OK is sent

xor

Name Type Required Restrictions Description
»» anonymous ServiceSubsystem false service subsystem specific configuration
»»» service object true
»»»» name string true Service name
»»»» type string true Service type

xor

Name Type Required Restrictions Description
»» anonymous DBusSubsystem false dbus subsystem specific configuration
»»» dbus object true
»»»» name string true Check name.
»»»» pattern string true DBus pattern to look for
»»»» watch string true DBus watch expression
»»»» alert_expiration integer false Number of seconds after which the alert is considered expired and an OK is sent
Enumerated Values
Property Value
type log
type service
type dbus

Toggle Channel Mute

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v1/devicemonitor/settings/global/channel/alerts/{name}/status \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

PUT https://hosted.mender.io/api/management/v1/devicemonitor/settings/global/channel/alerts/{name}/status HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "enabled": true
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/devicemonitor/settings/global/channel/alerts/{name}/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' => 'Bearer {access-token}'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v1/devicemonitor/settings/global/channel/alerts/{name}/status',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.put('https://hosted.mender.io/api/management/v1/devicemonitor/settings/global/channel/alerts/{name}/status', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/management/v1/devicemonitor/settings/global/channel/alerts/{name}/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/devicemonitor/settings/global/channel/alerts/{name}/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{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "https://hosted.mender.io/api/management/v1/devicemonitor/settings/global/channel/alerts/{name}/status", data)
    req.Header = headers

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

PUT /settings/global/channel/alerts/{name}/status

Enable or disable the named alert channel for all users.

Body parameter

{
  "enabled": true
}

Parameters

Name In Type Required Description
name path string true Channel name
body body object false
» enabled body boolean false Enable/disable channel
Enumerated Values
Parameter Value
name email

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content Update successful (no content) None
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error

Schemas

Error

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.
request_id string false Request ID passed with the request X-MEN-RequestID header or generated by the server.

Alert

{
  "name": "mender-connect systemd service",
  "level": "CRITICAL",
  "timestamp": "2019-07-21T17:32:28Z",
  "subject": {
    "name": "mender-connect",
    "status": "not-running",
    "type": "systemd.unit",
    "details": {
      "description": "Description of an error.",
      "lines_before": [
        {
          "line_number": 1,
          "data": "Line 1 from a log file"
        },
        {
          "line_number": 2,
          "data": "Line 2 from a log file"
        }
      ],
      "line_matching": {
        "line_number": 3,
        "data": "Line 3 from a log file"
      },
      "lines_after": [
        {
          "line_number": 4,
          "data": "Line 4 from a log file"
        },
        {
          "line_number": 5,
          "data": "Line 5 from a log file"
        }
      ]
    }
  }
}

Properties
Name Type Required Description
id string(uuid) false A unique ID for the alert.
name string false The name of the alert.
device_id string true
level string false Alert severity level
subject AlertSubject true Alert subject: the description of the alert origin
timestamp string(date-time) true Time and date when the alert occurred
Enumerated Values
Property Value
level OK
level CRITICAL

AlertSubject

{
  "name": "mender-connect",
  "status": "not-running",
  "type": "systemd.unit",
  "details": {
    "description": "Description of an error.",
    "lines_before": [
      {
        "line_number": 1,
        "data": "Line 1 from a log file"
      },
      {
        "line_number": 2,
        "data": "Line 2 from a log file"
      }
    ],
    "line_matching": {
      "line_number": 3,
      "data": "Line 3 from a log file"
    },
    "lines_after": [
      {
        "line_number": 4,
        "data": "Line 4 from a log file"
      },
      {
        "line_number": 5,
        "data": "Line 5 from a log file"
      }
    ]
  }
}

Alert subject: the description of the alert origin

Properties
Name Type Required Description
name string true Name of an entity that caused the alert
type string true The type of executable that triggered the alert
status string true Status of an entity that caused the alert
details AlertDetails false Additional details on the alert.

AlertDetails

{
  "description": "Description of an error.",
  "lines_before": [
    {
      "line_number": 1,
      "data": "Line 1 from a log file"
    },
    {
      "line_number": 2,
      "data": "Line 2 from a log file"
    }
  ],
  "line_matching": {
    "line_number": 3,
    "data": "Line 3 from a log file"
  },
  "lines_after": [
    {
      "line_number": 4,
      "data": "Line 4 from a log file"
    },
    {
      "line_number": 5,
      "data": "Line 5 from a log file"
    }
  ]
}

Additional details on the alert.

Properties
Name Type Required Description
description string false Alert description.
lines_before [LineDescriptor] false Log lines before matched pattern.
lines_after [LineDescriptor] false Log lines after matched pattern.
line_matching LineDescriptor false Describes the data and line of a pattern-matched log line.

LineDescriptor

{
  "line_number": 0,
  "data": "string"
}

Describes the data and line of a pattern-matched log line.

Properties
Name Type Required Description
line_number integer true
data string true

MonitorConfiguration

{
  "name": "string",
  "status": "string",
  "type": "log",
  "log": {
    "pattern": "string",
    "path": "string",
    "expire_seconds": 0
  }
}

Monitor configuration data.

Properties

allOf

Name Type Required Description
anonymous object false
» name string true
» status string true
» type string true

and - discriminator: type

Name Type Required Description
anonymous any false

oneOf

Name Type Required Description
» anonymous LogSubsystem false log subsystem specific configuration

xor

Name Type Required Description
» anonymous ServiceSubsystem false service subsystem specific configuration

xor

Name Type Required Description
» anonymous DBusSubsystem false dbus subsystem specific configuration
Enumerated Values
Property Value
type log
type service
type dbus

LogSubsystem

{
  "log": {
    "pattern": "string",
    "path": "string",
    "expire_seconds": 0
  }
}

log subsystem specific configuration

Properties
Name Type Required Description
log object true
» pattern string true Log pattern
» path string true Path to the log file or command to execute to get the logs (prefixed with '@').
» expire_seconds integer false Number of seconds after which the pattern is considered expired and an OK is sent

ServiceSubsystem

{
  "service": {
    "name": "string",
    "type": "string"
  }
}

service subsystem specific configuration

Properties
Name Type Required Description
service object true
» name string true Service name
» type string true Service type

DBusSubsystem

{
  "dbus": {
    "name": "string",
    "pattern": "string",
    "watch": "string",
    "alert_expiration": 0
  }
}

dbus subsystem specific configuration

Properties
Name Type Required Description
dbus object true
» name string true Check name.
» pattern string true DBus pattern to look for
» watch string true DBus watch expression
» alert_expiration integer false Number of seconds after which the alert is considered expired and an OK is sent

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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.
»» 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 type arrays are not allowed.
»» timestamp string(date-time) false The date and time of last tag update in RFC3339 format.
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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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"
    },
    {
      "name": "environment",
      "scope": "tags",
      "value": "test",
      "description": "Test environment",
      "timestamp": "2016-10-19T17:23:01.639Z"
    }
  ],
  "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
Response Headers
Status Header Type Format Description
200 ETag string Contains the device object's current ETag.

Applicable only to attributes with 'tags' scope, changing other attributes doesn't affect the ETag. |

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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

Add Tags

Code samples

# You can also use wget
curl -X PATCH https://hosted.mender.io/api/management/v1/inventory/devices/{id}/tags \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'If-Match: string' \
  -H 'Authorization: Bearer {access-token}'

PATCH https://hosted.mender.io/api/management/v1/inventory/devices/{id}/tags HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json
If-Match: string

const inputBody = '[
  {
    "name": "location",
    "value": "germany",
    "description": "Germany region"
  },
  {
    "name": "environment",
    "value": "test"
  }
]';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'If-Match':'string',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/inventory/devices/{id}/tags',
{
  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',
  'If-Match' => 'string',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'If-Match': 'string',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'If-Match' => 'string',
    'Authorization' => 'Bearer {access-token}',
);

$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/devices/{id}/tags', 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}/tags");
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"},
        "If-Match": []string{"string"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

PATCH /devices/{id}/tags

Adds a set of tags for a device

Saves the provided tags set for the authenticated device.

This method has upsert semantic:

Body parameter

[
  {
    "name": "location",
    "value": "germany",
    "description": "Germany region"
  },
  {
    "name": "environment",
    "value": "test"
  }
]

Parameters

Name In Type Required Description
If-Match header string false Contains the device object's current ETag, and performs the update only if it matches the one stored in the database.
id path string true Device identifier.
body body Tag true A list of tag descriptors.

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
200 OK Tags were updated successfully. 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
412 Precondition Failed ETag doesn't match. None
500 Internal Server Error Internal server error. Error

Assign Tags

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v1/inventory/devices/{id}/tags \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'If-Match: string' \
  -H 'Authorization: Bearer {access-token}'

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

const inputBody = '[
  {
    "name": "location",
    "value": "germany",
    "description": "Germany region"
  },
  {
    "name": "environment",
    "value": "test"
  }
]';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'If-Match':'string',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/inventory/devices/{id}/tags',
{
  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',
  'If-Match' => 'string',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'If-Match': 'string',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'If-Match' => 'string',
    'Authorization' => 'Bearer {access-token}',
);

$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}/tags', 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}/tags");
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"},
        "If-Match": []string{"string"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

PUT /devices/{id}/tags

Replace the set of tags for a device

Replaces the tags associated to the device.

This method replaces all the tags with the new set:

Body parameter

[
  {
    "name": "location",
    "value": "germany",
    "description": "Germany region"
  },
  {
    "name": "environment",
    "value": "test"
  }
]

Parameters

Name In Type Required Description
If-Match header string false Contains the device object's current ETag, and performs the update only if it matches the one stored in the database.
id path string true Device identifier.
body body Tag true A list of tags descriptors.

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
200 OK Tags were updated successfully. 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
412 Precondition Failed ETag doesn't match. 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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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

Remove a Group

Code samples

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

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/inventory/groups/{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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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}', 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}");
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{"Bearer {access-token}"},
    }

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

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

DELETE /groups/{name}

Remove a device group

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

Parameters

Name In Type Required Description
name path string true Group name.

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.

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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 the specified group.

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 remove from 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",
  "timestamp": "2016-10-19T17:23:01.639Z"
}

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 type arrays are not allowed.
timestamp string(date-time) false The date and time of last tag update in RFC3339 format.

Tag

{
  "name": "environment",
  "description": "Test environment",
  "value": "test",
  "timestamp": "2016-10-19T17:23:01.639Z"
}

Tag descriptor.

Properties
Name Type Required Description
name string true Tag is an attribute with 'tags' scope.

A human readable, unique tag ID, e.g. 'location', 'environment', etc.
description string false Tag description.
value string true The current value of the tag.
timestamp string(date-time) false The date and time of last tag update in RFC3339 format.

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:

Get filterable attributes

Code samples

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

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/inventory/filters/attributes',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/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/management/v2/inventory/filters/attributes");
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{"Bearer {access-token}"},
    }

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

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

GET /filters/attributes

Get the list of filterable inventory attributes

Returns a list of filterable inventory attributes.

The list is sorted in descending order by the count of occurrences of the attribute in the inventory database, then in ascending order by scope and name.

Limitations:

Example responses

200 Response

[
  {
    "name": "serial_no",
    "scope": "inventory",
    "count": 10
  }
]

Responses

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

Status Code 200

List of filter attributes

Name Type Required Restrictions Description
List of filter attributes [FilterAttribute] false [Filterable attribute]
» name string true Name of the attribute.
» scope string true Scope of the attribute.
» count integer true Number of occurrences of the attribute in the database.

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: Bearer {access-token}'

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,
  "text": "string",
  "filters": [
    {
      "attribute": "serial_no",
      "scope": "inventory",
      "type": "$eq",
      "value": "123456789"
    }
  ],
  "sort": [
    {
      "attribute": "serial_no",
      "scope": "inventory",
      "order": "asc"
    }
  ],
  "attributes": [
    {
      "attribute": "serial_no",
      "scope": "inventory"
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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.

Body parameter

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

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.
» text body string false Free-text search query
» filters body [FilterPredicate] false List of filter predicates.
»» attribute body string true Attribute name.
»» scope body string true
»» 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
»» attribute body string true Attribute name.
»» scope body string true Attribute scope.
»» order body string true Order direction, ascending ("asc") or descending ("desc").
» attributes body [SelectAttribute] false List of attributes to select and return
»» attribute body string true Attribute name.
»» scope body string true Attribute scope.
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
$ltne Less than or does not exist 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 $ltne
»» 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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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]
»» attribute string true Attribute name.
»» scope string true
»» 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 $ltne
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: Bearer {access-token}'

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": "My filter",
  "terms": [
    {
      "attribute": "serial_no",
      "scope": "inventory",
      "type": "$eq",
      "value": "123456789"
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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": "My filter",
  "terms": [
    {
      "attribute": "serial_no",
      "scope": "inventory",
      "type": "$eq",
      "value": "123456789"
    }
  ]
}

Parameters

Name In Type Required Description
body body FilterDefinition false The definition of the filter

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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

Update Filter

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v2/inventory/filters/{id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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

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

fetch('https://hosted.mender.io/api/management/v2/inventory/filters/{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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

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

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('PUT','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("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{"Bearer {access-token}"},
    }

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

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

PUT /filters/{id}

Update a saved filter

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

Body parameter

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

Parameters

Name In Type Required Description
id path string true Filter identifier.
body body FilterDefinition false The definition of the filter

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 updated. None
400 Bad Request Missing or malformed request parameters. See error for details. Error
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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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).

FilterAttribute

{
  "name": "serial_no",
  "scope": "inventory",
  "count": 10
}

Filterable attribute

Properties
Name Type Required Description
name string true Name of the attribute.
scope string true Scope of the attribute.
count integer true Number of occurrences of the attribute in the database.

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]

FilterDefinition

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

Filter definition

Properties
Name Type Required Description
name string false Name of the filter, must be unique.
terms [FilterPredicate] false List of filter predicates, chained with boolean AND operators to build the search condition definition.

FilterPredicate

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

Attribute filter predicate

Properties
Name Type Required Description
attribute string true Attribute name.
scope string true
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 $ltne
type $ne
type $nin
type $exists
type $regex

SelectAttribute

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

Inventory attribute

Properties
Name Type Required Description
attribute string true Attribute name.
scope string true Attribute scope.

SortCriteria

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

Sort criteria definition

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

IoT Manager

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

API for managing IoT Cloud integrations. Intended for use by the web GUI

Base URLs:

List integrations

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/iot-manager/integrations \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v1/iot-manager/integrations HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/iot-manager/integrations',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://hosted.mender.io/api/management/v1/iot-manager/integrations', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/iot-manager/integrations', 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/iot-manager/integrations");
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{"Bearer {access-token}"},
    }

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

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

GET /integrations

List all configured integrations

Parameters

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

Example responses

200 Response

[
  {
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "provider": "iot-hub",
    "credentials": {
      "type": "aws",
      "aws": {}
    },
    "description": "string"
  }
]

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

401 Response

{
  "error": "Unauthorized",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

403 Response

{
  "error": "Forbidden",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
200 OK OK. Returns list of integrations. Inline
400 Bad Request Invalid Request. Error
401 Unauthorized The user does not have authorization to access resource. Error
403 Forbidden The user is not permitted to access the resource. Error
500 Internal Server Error Internal Server Error. Error
Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [Integration] false
» id string(uuid) false A unique integration identifier generated by the mender server
» provider string true
» credentials any true

allOf

Name Type Required Restrictions Description
»» anonymous object false
»»» type string true The credential type

and

Name Type Required Restrictions Description
»» anonymous any false

oneOf

Name Type Required Restrictions Description
»»» anonymous AWSCredentials false AWS credentials in the form of access key id and secret access key, a region and a
device policy name.
»»»» aws object true
»»»»» access_key_id string true
»»»»» secret_access_key string true
»»»»» region string true
»»»»» device_policy_name string true

xor

Name Type Required Restrictions Description
»»» anonymous AzureSharedAccessSecret false Shared Access Secret is an authentication mechanism in the form of a
connection string for Azure IoT Hub.
»»»» connection_string string true

xor

Name Type Required Restrictions Description
»»» anonymous HTTP false HTTP Webhook configuration.
»»»» http object true
»»»»» url string true The destination URL for the webhook. The webhook will send POST requests with event details to this target URL.
»»»»» secret string false An optional secret used to verify the integrity of the payload. The string must be in hexadecimal format.

continued

Name Type Required Restrictions Description
» description string false A short human readable description (max 1024 characters).
Enumerated Values
Property Value
provider iot-hub
provider iot-core
provider webhook
type aws
type sas
type http

Register integration

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/iot-manager/integrations \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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

const inputBody = '{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "provider": "iot-hub",
  "credentials": {
    "type": "aws",
    "aws": {
      "access_key_id": null,
      "secret_access_key": null,
      "region": null,
      "device_policy_name": null
    }
  },
  "description": "string"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/iot-manager/integrations',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

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

r = requests.post('https://hosted.mender.io/api/management/v1/iot-manager/integrations', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v1/iot-manager/integrations', 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/iot-manager/integrations");
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{"Bearer {access-token}"},
    }

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

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

POST /integrations

Register a new cloud integration

Body parameter

{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "provider": "iot-hub",
  "credentials": {
    "type": "aws",
    "aws": {
      "access_key_id": null,
      "secret_access_key": null,
      "region": null,
      "device_policy_name": null
    }
  },
  "description": "string"
}

Parameters

Name In Type Required Description
body body Integration true

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

401 Response

{
  "error": "Unauthorized",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

403 Response

{
  "error": "Forbidden",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
201 Created Integration registered. None
400 Bad Request Invalid Request. Error
401 Unauthorized The user does not have authorization to access resource. Error
403 Forbidden The user is not permitted to access the resource. Error
500 Internal Server Error Internal Server Error. Error
Response Headers
Status Header Type Format Description
201 Location string URL of the newly registered integration.

Remove integration

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v1/iot-manager/integrations/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

DELETE https://hosted.mender.io/api/management/v1/iot-manager/integrations/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/iot-manager/integrations/{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' => 'Bearer {access-token}'
}

result = RestClient.delete 'https://hosted.mender.io/api/management/v1/iot-manager/integrations/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.delete('https://hosted.mender.io/api/management/v1/iot-manager/integrations/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('DELETE','https://hosted.mender.io/api/management/v1/iot-manager/integrations/{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/iot-manager/integrations/{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{"Bearer {access-token}"},
    }

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

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

DELETE /integrations/{id}

Remove a cloud integration

Parameters

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

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

401 Response

{
  "error": "Unauthorized",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

403 Response

{
  "error": "Forbidden",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content Integration unregistered successfully. None
400 Bad Request Invalid Request. Error
401 Unauthorized The user does not have authorization to access resource. Error
403 Forbidden The user is not permitted to access the resource. Error
500 Internal Server Error Internal Server Error. Error

Set integration credentials

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v1/iot-manager/integrations/{id}/credentials \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

PUT https://hosted.mender.io/api/management/v1/iot-manager/integrations/{id}/credentials HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "type": "aws",
  "aws": {
    "access_key_id": "string",
    "secret_access_key": "string",
    "region": "string",
    "device_policy_name": "string"
  }
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/iot-manager/integrations/{id}/credentials',
{
  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' => 'Bearer {access-token}'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v1/iot-manager/integrations/{id}/credentials',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.put('https://hosted.mender.io/api/management/v1/iot-manager/integrations/{id}/credentials', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/management/v1/iot-manager/integrations/{id}/credentials', 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/iot-manager/integrations/{id}/credentials");
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{"Bearer {access-token}"},
    }

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

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

PUT /integrations/{id}/credentials

Replace the credentials associated with the integration.

Body parameter

{
  "type": "aws",
  "aws": {
    "access_key_id": "string",
    "secret_access_key": "string",
    "region": "string",
    "device_policy_name": "string"
  }
}

Parameters

Name In Type Required Description
id path string true Integration identifier.
body body Credentials true

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

401 Response

{
  "error": "Unauthorized",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

403 Response

{
  "error": "Forbidden",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

404 Response

{
  "error": "not found",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content Credentials updated successfully. None
400 Bad Request Invalid Request. Error
401 Unauthorized The user does not have authorization to access resource. Error
403 Forbidden The user is not permitted to access the resource. Error
404 Not Found Resource not found. Error
500 Internal Server Error Internal Server Error. Error

Unregister device integrations

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

DELETE https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}',
{
  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' => 'Bearer {access-token}'
}

result = RestClient.delete 'https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.delete('https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('DELETE','https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}', 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/iot-manager/devices/{deviceId}");
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{"Bearer {access-token}"},
    }

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

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

DELETE /devices/{deviceId}

Removes all associated cloud integrations for the device.

Removes all associated cloud integrations for the device, but does not clean up any external state.

Parameters

Name In Type Required Description
deviceId path string true The unique ID of the device.

Example responses

204 Response

{
  "desired": {},
  "reported": {}
}

401 Response

{
  "error": "Unauthorized",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

403 Response

{
  "error": "Forbidden",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

404 Response

{
  "error": "not found",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content OK. Device successfully unregistered. DeviceState
401 Unauthorized The user does not have authorization to access resource. Error
403 Forbidden The user is not permitted to access the resource. Error
404 Not Found Resource not found. Error
500 Internal Server Error Internal Server Error. Error

Get Device States

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state',
{
  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' => 'Bearer {access-token}'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state', 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/iot-manager/devices/{deviceId}/state");
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{"Bearer {access-token}"},
    }

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

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

GET /devices/{deviceId}/state

Gets the desired and reported state of a device

Parameters

Name In Type Required Description
deviceId path string true The unique ID of the device.

Example responses

200 Response

{
  "property1": {
    "desired": {},
    "reported": {}
  },
  "property2": {
    "desired": {},
    "reported": {}
  }
}

401 Response

{
  "error": "Unauthorized",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

403 Response

{
  "error": "Forbidden",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

404 Response

{
  "error": "not found",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
200 OK OK. Returns device reported and desired states for all integrations. Inline
401 Unauthorized The user does not have authorization to access resource. Error
403 Forbidden The user is not permitted to access the resource. Error
404 Not Found Resource not found. Error
500 Internal Server Error Internal Server Error. Error
Response Schema

Status Code 200

Mapping from integration ID to DeviceState objects for all applicable integrations.

Name Type Required Restrictions Description
» additionalProperties DeviceState false
»» desired object false The desired state for the device, as reported by the cloud/user.
»» reported object false State reported by the device, this cannot be changed from the cloud.

Replace State

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state/{integrationId} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

PUT https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state/{integrationId} HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "desired": {},
  "reported": {}
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state/{integrationId}',
{
  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' => 'Bearer {access-token}'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state/{integrationId}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.put('https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state/{integrationId}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state/{integrationId}', 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/iot-manager/devices/{deviceId}/state/{integrationId}");
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{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state/{integrationId}", data)
    req.Header = headers

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

PUT /devices/{deviceId}/state/{integrationId}

Replaces the (desired) cloud state of the device for the given integration

Body parameter

{
  "desired": {},
  "reported": {}
}

Parameters

Name In Type Required Description
deviceId path string true The unique ID of the device.
integrationId path string true The unique ID of the integration.
body body DeviceState true

Example responses

200 Response

{
  "desired": {},
  "reported": {}
}

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

401 Response

{
  "error": "Unauthorized",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

403 Response

{
  "error": "Forbidden",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

409 Response

{
  "error": "Conflict",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
200 OK OK. Returns the updated device state. DeviceState
400 Bad Request Invalid Request. Error
401 Unauthorized The user does not have authorization to access resource. Error
403 Forbidden The user is not permitted to access the resource. Error
409 Conflict Conflict when updating the resource. Error
500 Internal Server Error Internal Server Error. Error

Get Device State

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state/{integrationId} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state/{integrationId} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state/{integrationId}',
{
  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' => 'Bearer {access-token}'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state/{integrationId}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state/{integrationId}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/iot-manager/devices/{deviceId}/state/{integrationId}', 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/iot-manager/devices/{deviceId}/state/{integrationId}");
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{"Bearer {access-token}"},
    }

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

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

GET /devices/{deviceId}/state/{integrationId}

Gets the desired and reported state of a device from an integration

Parameters

Name In Type Required Description
deviceId path string true The unique ID of the device.
integrationId path string true The unique ID of the integration.

Example responses

200 Response

{
  "desired": {},
  "reported": {}
}

401 Response

{
  "error": "Unauthorized",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

403 Response

{
  "error": "Forbidden",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

404 Response

{
  "error": "not found",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
200 OK OK. Returns device reported and desired state for the integration. DeviceState
401 Unauthorized The user does not have authorization to access resource. Error
403 Forbidden The user is not permitted to access the resource. Error
404 Not Found Resource not found. Error
500 Internal Server Error Internal Server Error. Error

List events

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/iot-manager/events \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v1/iot-manager/events HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/iot-manager/events',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://hosted.mender.io/api/management/v1/iot-manager/events', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/iot-manager/events', 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/iot-manager/events");
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{"Bearer {access-token}"},
    }

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

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

GET /events

List all stored events

Parameters

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

Example responses

200 Response

[
  {
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "type": "device-provisioned",
    "delivery_statuses": [
      {
        "integration_id": "string",
        "success": true,
        "status_code": 0,
        "error": "string"
      }
    ],
    "time": "2019-08-24T14:15:22Z",
    "data": {
      "id": "string",
      "status": "string",
      "auth_sets": [
        {
          "id": null,
          "device_id": null,
          "identity_data": null,
          "pubkey": null,
          "status": null,
          "ts": null
        }
      ],
      "created_ts": "2019-08-24T14:15:22Z"
    }
  }
]

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

401 Response

{
  "error": "Unauthorized",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

403 Response

{
  "error": "Forbidden",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
200 OK OK. Returns list of events. Inline
400 Bad Request Invalid Request. Error
401 Unauthorized The user does not have authorization to access resource. Error
403 Forbidden The user is not permitted to access the resource. Error
500 Internal Server Error Internal Server Error. Error
Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [Event] false
» id string(uuid) false A unique event identifier generated by the Mender server
» type string false Type of the event
» delivery_statuses [object] false
»» integration_id string true The ID of the integration the status belongs.
»» success boolean true Whether the event hook was executed successfully.
»» status_code integer false The (HTTP) status code of the hook.
»» error string false An error message if the hook failed.
» time string(date-time) false Creation timestamp
» data DeviceAuthEvent false DeviceAuthEvent describes an event that relates to changes to a device's authentication data. The properties included depends on the event type: device provisioning includes the entire device with the accepted authentication set, status change events only includes the device id and the new status, and device decommissioning will only include the device id.
»» id string true Device unique ID.
»» status string false The authentication status of the device.
»» auth_sets [AuthSet] false [AuthSet describes the identity a device use to authenticate with the Mender servier.]
»»» id string false The unique ID of the authentication set.
»»» device_id string false The unique ID of the device the authentication set belongs.
»»» identity_data object false The identity data presented by the device.
»»» pubkey string false PEM-encoded public key of the device authentication set.
»»» status string false Authentication status of the set.
»»» ts string false The creation timestamp of the authentication set.
»» created_ts string(date-time) false The time the device was initialized in Mender.
Enumerated Values
Property Value
type device-provisioned
type device-decommissioned
type device-status-changed

Schemas

Integration

{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "provider": "iot-hub",
  "credentials": {
    "type": "aws",
    "aws": {
      "access_key_id": null,
      "secret_access_key": null,
      "region": null,
      "device_policy_name": null
    }
  },
  "description": "string"
}

Properties
Name Type Required Description
id string(uuid) false A unique integration identifier generated by the mender server
provider string true
credentials Credentials true
description string false A short human readable description (max 1024 characters).
Enumerated Values
Property Value
provider iot-hub
provider iot-core
provider webhook

Credentials

{
  "type": "aws",
  "aws": {
    "access_key_id": "string",
    "secret_access_key": "string",
    "region": "string",
    "device_policy_name": "string"
  }
}

Properties

allOf

Name Type Required Description
anonymous object false
» type string true The credential type

and

Name Type Required Description
anonymous any false

oneOf

Name Type Required Description
» anonymous AWSCredentials false AWS credentials in the form of access key id and secret access key, a region and a
device policy name.

xor

Name Type Required Description
» anonymous AzureSharedAccessSecret false Shared Access Secret is an authentication mechanism in the form of a
connection string for Azure IoT Hub.

xor

Name Type Required Description
» anonymous HTTP false HTTP Webhook configuration.
Enumerated Values
Property Value
type aws
type sas
type http

AWSCredentials

{
  "aws": {
    "access_key_id": "string",
    "secret_access_key": "string",
    "region": "string",
    "device_policy_name": "string"
  }
}

AWS credentials in the form of access key id and secret access key, a region and a device policy name.

Properties
Name Type Required Description
aws object true
» access_key_id string true
» secret_access_key string true
» region string true
» device_policy_name string true

AzureSharedAccessSecret

{
  "connection_string": "string"
}

Shared Access Secret is an authentication mechanism in the form of a connection string for Azure IoT Hub.

Properties
Name Type Required Description
connection_string string true

DeviceState

{
  "desired": {},
  "reported": {}
}

Properties
Name Type Required Description
desired object false The desired state for the device, as reported by the cloud/user.
reported object false State reported by the device, this cannot be changed from the cloud.

HTTP

{
  "http": {
    "url": "string",
    "secret": "string"
  }
}

HTTP Webhook configuration.

Properties
Name Type Required Description
http object true
» url string true The destination URL for the webhook. The webhook will send POST requests with event details to this target URL.
» secret string false An optional secret used to verify the integrity of the payload. The string must be in hexadecimal format.

Error

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.
request_id string false Request ID passed with the request X-Men-Requestid header or generated by the server.

Event

{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "type": "device-provisioned",
  "delivery_statuses": [
    {
      "integration_id": "string",
      "success": true,
      "status_code": 0,
      "error": "string"
    }
  ],
  "time": "2019-08-24T14:15:22Z",
  "data": {
    "id": "string",
    "status": "string",
    "auth_sets": [
      {
        "id": "string",
        "device_id": "string",
        "identity_data": {},
        "pubkey": "string",
        "status": "string",
        "ts": "string"
      }
    ],
    "created_ts": "2019-08-24T14:15:22Z"
  }
}

Properties
Name Type Required Description
id string(uuid) false A unique event identifier generated by the Mender server
type string false Type of the event
delivery_statuses [object] false
» integration_id string true The ID of the integration the status belongs.
» success boolean true Whether the event hook was executed successfully.
» status_code integer false The (HTTP) status code of the hook.
» error string false An error message if the hook failed.
time string(date-time) false Creation timestamp
data DeviceAuthEvent false DeviceAuthEvent describes an event that relates to changes to a device's authentication data. The properties included depends on the event type: device provisioning includes the entire device with the accepted authentication set, status change events only includes the device id and the new status, and device decommissioning will only include the device id.
Enumerated Values
Property Value
type device-provisioned
type device-decommissioned
type device-status-changed

DeviceAuthEvent

{
  "id": "string",
  "status": "string",
  "auth_sets": [
    {
      "id": "string",
      "device_id": "string",
      "identity_data": {},
      "pubkey": "string",
      "status": "string",
      "ts": "string"
    }
  ],
  "created_ts": "2019-08-24T14:15:22Z"
}

DeviceAuthEvent describes an event that relates to changes to a device's authentication data. The properties included depends on the event type: device provisioning includes the entire device with the accepted authentication set, status change events only includes the device id and the new status, and device decommissioning will only include the device id.

Properties
Name Type Required Description
id string true Device unique ID.
status string false The authentication status of the device.
auth_sets [AuthSet] false [AuthSet describes the identity a device use to authenticate with the Mender servier.]
created_ts string(date-time) false The time the device was initialized in Mender.

AuthSet

{
  "id": "string",
  "device_id": "string",
  "identity_data": {},
  "pubkey": "string",
  "status": "string",
  "ts": "string"
}

AuthSet describes the identity a device use to authenticate with the Mender servier.

Properties
Name Type Required Description
id string false The unique ID of the authentication set.
device_id string false The unique ID of the device the authentication set belongs.
identity_data object false The identity data presented by the device.
pubkey string false PEM-encoded public key of the device authentication set.
status string false Authentication status of the set.
ts string false The creation timestamp of the authentication set.

Tenants

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 user-facing API to tenant administration service

Base URLs:

Tenant Info

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/tenantadm/user/tenant \
  -H 'Accept: */*' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v1/tenantadm/user/tenant HTTP/1.1
Host: hosted.mender.io
Accept: */*


const headers = {
  'Accept':'*/*',
  'Authorization':'Bearer {access-token}'
};

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

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => '*/*',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': '*/*',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => '*/*',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v1/tenantadm/user/tenant', 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/tenantadm/user/tenant");
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{"*/*"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

GET /user/tenant

Obtain information about current tenant

The returned tenant resolves to the owner of the subject claim (user unique ID) in the JWT token.

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK A tenant descriptor is returned. Tenant
401 Unauthorized Verification failed. None
404 Not Found User is not a part of any tenant organization. Error
500 Internal Server Error Unexpected error. Error

Schemas

Tenant

{
  "id": "507f191e810c19729de860ea",
  "name": "Acme",
  "tenant_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODcwNTU3MzUsImp0aSI6IjM5MTJiZDNmLWVjMTEtNDgwNy05MmE4LTBkOTVjMWFmYjU1NCIsImlzcyI6Ik1lbmRlciIsInN1YiI6ImQ0NTljOTFmZDkzMWFkOGM0ZDk4ZGIyZjdlZjU3NjYxNDI3NDJiZDMyMzM0ZjIyNjYyZTNiNjE5YmRiZTJhNTYifQ.iY2XuyuDOHW9ilPPeeHuwmz9A-6asDqdfy3mCjXuODns1SshbuH_XXFPa7s2PpXCMkhEHB82nLEjwcSO7gTIz1uqzjyGufVbXlOiZqPrCXUm4DKvhSgANiVKfkw_JvD1w-V0jyctBcrUifIhqhRlhXNAJh3c5XAMzxe2kwt9t3JW5bXiXroc64gXdv0gnX-o7YgdrFfau3rAaMFinKqHzACmeE5YhEVF9eQPJQ99U0PO6tVCcG39O-vtt51ClWh3BVeeQrHcr5eWQZWFMHThdeoRitLwvsN8wzrEKUoL9q9SlFnu4uGJkfOfTuiafgF1pJ-UBDYdBdV4sV9626PdHQ",
  "status": "active"
}

Tenant descriptor.

Properties
Name Type Required Description
id string true Tenant ID.
name string true Name of the tenant's organization.
tenant_token string true Currently used tenant token.
status string false Status of the tenant account.
api_limits TenantApiLimits false API usage quota and burst limit definitions for a tenant - per API type.
addons [Addon] false [Mender addon definition.]
Enumerated Values
Property Value
status active
status suspended

ApiBurst

{
  "action": "PATCH",
  "uri": "/api/devices/v1/inventory/device/attributes",
  "min_interval_sec": 10
}

API burst limit definition.

Properties
Name Type Required Description
action string false HTTP verb.
uri string false URI of the resource subject to the limit.
min_interval_sec integer false Minimum allowed interval, in seconds, between subsequent calls to 'action' on 'uri' (10 = one call every 10 seconds, etc.)

ApiQuota

{
  "max_calls": 100,
  "interval_sec": 3600
}

API usage quota definition.

Properties
Name Type Required Description
max_calls integer false Maximum allowed number of calls within 'interval'.
interval_sec integer false Interval definition, in seconds (60 = 1 minute, 3600 = 1 hour, etc.).

ApiLimits

{
  "bursts": [
    {
      "action": "PATCH",
      "uri": "/api/devices/v1/inventory/device/attributes",
      "min_interval_sec": 10
    },
    {
      "action": "POST",
      "uri": "/api/devices/v1/deployments/device/deployments/next",
      "min_interval_sec": 60
    }
  ],
  "quota": {
    "max_calls": 100,
    "interval_sec": 60
  }
}

Usage quota and burst limit definitions for an API type.

Properties
Name Type Required Description
bursts [ApiBurst] false Collection of api burst limit definitions over specified API resources.
quota ApiQuota false API usage quota definition.

TenantApiLimits

{
  "management": {
    "quota": {
      "max_calls": 100,
      "interval_sec": 60
    }
  },
  "devices": {
    "quota": {
      "max_calls": 1000,
      "interval_sec": 60
    },
    "bursts": [
      {
        "action": "PATCH",
        "uri": "/api/devices/v1/inventory/device/attributes",
        "min_interval_sec": 10
      },
      {
        "action": "POST",
        "uri": "/api/devices/v1/deployments/device/deployments/next",
        "min_interval_sec": 60
      }
    ]
  }
}

API usage quota and burst limit definitions for a tenant - per API type.

Properties
Name Type Required Description
management ApiLimits false Usage quota and burst limit definitions for an API type.
devices ApiLimits false Usage quota and burst limit definitions for an API type.

Addon

{
  "name": "troubleshoot",
  "enabled": true
}

Mender addon definition.

Properties
Name Type Required Description
name string false Name of the addon (one of ['configure', 'troubleshoot']).
enabled boolean false Enabled/disabled flag.

Error

{
  "error": "tenant_token is invalid",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.

Tenants 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 user-facing API to tenant administration service

Base URLs:

List Tenants

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/tenantadm/tenants \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/tenants',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v2/tenantadm/tenants', 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/tenantadm/tenants");
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{"Bearer {access-token}"},
    }

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

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

GET /tenants

List the children Tenants associated with a Service Provider Tenant

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.

Example responses

200 Response

[
  {
    "id": "507f191e810c19729de860ea",
    "name": "Acme",
    "tenant_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODcwNTU3MzUsImp0aSI6IjM5MTJiZDNmLWVjMTEtNDgwNy05MmE4LTBkOTVjMWFmYjU1NCIsImlzcyI6Ik1lbmRlciIsInN1YiI6ImQ0NTljOTFmZDkzMWFkOGM0ZDk4ZGIyZjdlZjU3NjYxNDI3NDJiZDMyMzM0ZjIyNjYyZTNiNjE5YmRiZTJhNTYifQ.iY2XuyuDOHW9ilPPeeHuwmz9A-6asDqdfy3mCjXuODns1SshbuH_XXFPa7s2PpXCMkhEHB82nLEjwcSO7gTIz1uqzjyGufVbXlOiZqPrCXUm4DKvhSgANiVKfkw_JvD1w-V0jyctBcrUifIhqhRlhXNAJh3c5XAMzxe2kwt9t3JW5bXiXroc64gXdv0gnX-o7YgdrFfau3rAaMFinKqHzACmeE5YhEVF9eQPJQ99U0PO6tVCcG39O-vtt51ClWh3BVeeQrHcr5eWQZWFMHThdeoRitLwvsN8wzrEKUoL9q9SlFnu4uGJkfOfTuiafgF1pJ-UBDYdBdV4sV9626PdHQ",
    "status": "active"
  }
]

Responses

Status Meaning Description Schema
200 OK List of tenants is returned Inline
500 Internal Server Error Internal server error. Error
Response Schema

Status Code 200

ListOfTenants

Name Type Required Restrictions Description
ListOfTenants [Tenant] false [Tenant descriptor.]
» id string true Tenant ID.
» name string true Name of the tenant's organization.
» tenant_token string true Currently used tenant token.
» status string false Status of the tenant account.
» api_limits TenantApiLimits false API usage quota and burst limit definitions for a tenant - per API type.
»» management ApiLimits false Usage quota and burst limit definitions for an API type.
»»» bursts [ApiBurst] false Collection of api burst limit definitions over specified API resources.
»»»» action string false HTTP verb.
»»»» uri string false URI of the resource subject to the limit.
»»»» min_interval_sec integer false Minimum allowed interval, in seconds, between subsequent calls to 'action' on 'uri' (10 = one call every 10 seconds, etc.)
»»» quota ApiQuota false API usage quota definition.
»»»» max_calls integer false Maximum allowed number of calls within 'interval'.
»»»» interval_sec integer false Interval definition, in seconds (60 = 1 minute, 3600 = 1 hour, etc.).
»» devices ApiLimits false Usage quota and burst limit definitions for an API type.
» addons [Addon] false [Mender addon definition.]
»» name string false Name of the addon (one of ['configure', 'troubleshoot']).
»» enabled boolean false Enabled/disabled flag.
Enumerated Values
Property Value
status active
status suspended
Response Headers
Status Header Type Format Description
200 Link string Standard header, used for page navigation.

Supported relation types are 'first', 'next' and 'prev'. |

Create new Tenant

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/tenantadm/tenants \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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

const inputBody = '{
  "name": "string",
  "admin": {
    "email": "string",
    "password": "string",
    "login": {}
  },
  "plan": "string",
  "device_limit": 0,
  "addons": [
    "string"
  ],
  "binary_delta": {
    "enabled": true,
    "binary_delta": {
      "xdelta_args": {
        "disable_checksum": false,
        "disable_external_decompression": false,
        "compression_level": 6,
        "source_window_size": 0,
        "input_window_size": 0,
        "compression_duplicates_window": 0,
        "instruction_buffer_size": 0
      },
      "timeout": 0
    },
    "binary_delta_limits": {
      "xdelta_args_limits": {
        "compression_level": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "source_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "input_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "compression_duplicates_window": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "instruction_buffer_size": {
          "min": 5,
          "max": 100,
          "default": 10
        }
      },
      "timeout": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "jobs_in_parallel": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "queue_length": {
        "min": 5,
        "max": 100,
        "default": 10
      }
    }
  },
  "sso": true
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/tenants',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

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

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v2/tenantadm/tenants', 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/tenantadm/tenants");
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{"Bearer {access-token}"},
    }

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

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

POST /tenants

Create a new Tenant associated with a Service Provider Tenant

Body parameter

{
  "name": "string",
  "admin": {
    "email": "string",
    "password": "string",
    "login": {}
  },
  "plan": "string",
  "device_limit": 0,
  "addons": [
    "string"
  ],
  "binary_delta": {
    "enabled": true,
    "binary_delta": {
      "xdelta_args": {
        "disable_checksum": false,
        "disable_external_decompression": false,
        "compression_level": 6,
        "source_window_size": 0,
        "input_window_size": 0,
        "compression_duplicates_window": 0,
        "instruction_buffer_size": 0
      },
      "timeout": 0
    },
    "binary_delta_limits": {
      "xdelta_args_limits": {
        "compression_level": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "source_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "input_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "compression_duplicates_window": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "instruction_buffer_size": {
          "min": 5,
          "max": 100,
          "default": 10
        }
      },
      "timeout": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "jobs_in_parallel": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "queue_length": {
        "min": 5,
        "max": 100,
        "default": 10
      }
    }
  },
  "sso": true
}

Parameters

Name In Type Required Description
body body NewTenant true New Tenant

Example responses

400 Response

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

Responses

Status Meaning Description Schema
202 Accepted Request to create tenant was accepted None
400 Bad Request The request body is malformed. Error
403 Forbidden Forbidden because the current tenant is not a service provider. Error
409 Conflict Tenant or admin user is duplicated. Error
500 Internal Server Error Internal server error. Error

Sign up

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/tenantadm/tenants/signup \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept: application/json'

POST https://hosted.mender.io/api/management/v2/tenantadm/tenants/signup HTTP/1.1
Host: hosted.mender.io
Content-Type: application/x-www-form-urlencoded
Accept: application/json

const inputBody = '{
  "organization": "string",
  "email": "user@example.com",
  "password": "string",
  "g-recaptcha-response": "string",
  "name": "string",
  "subscription_type": "trial",
  "subscription_token": "string",
  "campaign": "string",
  "ts": 0
}';
const headers = {
  'Content-Type':'application/x-www-form-urlencoded',
  'Accept':'application/json'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/tenants/signup',
{
  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/x-www-form-urlencoded',
  'Accept' => 'application/json'
}

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

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Accept': 'application/json'
}

r = requests.post('https://hosted.mender.io/api/management/v2/tenantadm/tenants/signup', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/x-www-form-urlencoded',
    '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/v2/tenantadm/tenants/signup', 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/tenantadm/tenants/signup");
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/x-www-form-urlencoded"},
        "Accept": []string{"application/json"},
    }

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

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

POST /tenants/signup

Create a new Account

Body parameter

organization: string
email: user@example.com
password: string
g-recaptcha-response: string
name: string
subscription_type: trial
subscription_token: string
campaign: string
ts: 0

Parameters

Name In Type Required Description
body body object true
» organization body string true Organization name (ASCII characters only, max 100 characters)
» email body string(email) true Email address (ASCII characters only)
» password body string true Password
» g-recaptcha-response body string true reCAPTCHA response
» name body string false customer name
» subscription_type body string false
» subscription_token body string false Subscription token is used to resolve the externally managed
» campaign body string false Campaign
» ts body integer false captcha timestamp
Detailed descriptions

» subscription_token: Subscription token is used to resolve the externally managed subscription. The token is required if subscription_type is "azure".

Enumerated Values
Parameter Value
» subscription_type trial
» subscription_type azure

Example responses

400 Response

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

Responses

Status Meaning Description Schema
202 Accepted Request to create organization was accepted None
400 Bad Request The request body is malformed. Error
401 Unauthorized Recaptcha verififaction failed. Error
405 Method Not Allowed Endpoint disabled. Error
409 Conflict Email is duplicated. Error
500 Internal Server Error Internal server error. Error
Response Headers
Status Header Type Format Description
202 Location string URL to log in to the newly created organization.

Create Trial Account

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/tenantadm/tenants/trial \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept: application/json'

POST https://hosted.mender.io/api/management/v2/tenantadm/tenants/trial HTTP/1.1
Host: hosted.mender.io
Content-Type: application/x-www-form-urlencoded
Accept: application/json

const inputBody = '{
  "organization": "string",
  "email": "user@example.com",
  "password": "string",
  "g-recaptcha-response": "string",
  "name": "string",
  "plan": "os",
  "campaign": "string",
  "ts": 0
}';
const headers = {
  'Content-Type':'application/x-www-form-urlencoded',
  'Accept':'application/json'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/tenants/trial',
{
  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/x-www-form-urlencoded',
  'Accept' => 'application/json'
}

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

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Accept': 'application/json'
}

r = requests.post('https://hosted.mender.io/api/management/v2/tenantadm/tenants/trial', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/x-www-form-urlencoded',
    '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/v2/tenantadm/tenants/trial', 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/tenantadm/tenants/trial");
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/x-www-form-urlencoded"},
        "Accept": []string{"application/json"},
    }

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

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

POST /tenants/trial

Create a trial organization

Body parameter

organization: string
email: user@example.com
password: string
g-recaptcha-response: string
name: string
plan: os
campaign: string
ts: 0

Parameters

Name In Type Required Description
body body object true
» organization body string true Organization name (ASCII characters only, max 100 characters)
» email body string(email) true Email address (ASCII characters only)
» password body string true Password
» g-recaptcha-response body string true reCAPTCHA response
» name body string false customer name
» plan body string false customer plan
» campaign body string false Campaign
» ts body integer false captcha timestamp
Enumerated Values
Parameter Value
» plan os
» plan professional
» plan enterprise

Example responses

400 Response

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

Responses

Status Meaning Description Schema
202 Accepted Request to create organization was accepted None
400 Bad Request The request body is malformed. Error
401 Unauthorized Recaptcha verififaction failed. Error
405 Method Not Allowed Endpoint disabled. Error
409 Conflict Email is duplicated. Error
500 Internal Server Error Internal server error. Error
Response Headers
Status Header Type Format Description
202 Location string URL to log in to the newly created organization.

Delete Inactive Account

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/tenants/{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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('DELETE','https://hosted.mender.io/api/management/v2/tenantadm/tenants/{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/tenantadm/tenants/{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{"Bearer {access-token}"},
    }

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

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

DELETE /tenants/{id}

Remove inactive tenant from the system.

Remove inactive tenant information from the system.

Parameters

Name In Type Required Description
id path string true Tenant ID.

Example responses

405 Response

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

Responses

Status Meaning Description Schema
204 No Content Tenant removed. None
405 Method Not Allowed The tenant cannot be removed.
Only inactive tenant can be removed. Error
500 Internal Server Error Internal server error. Error

Update Child Tenant

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/child \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

PUT https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/child HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "name": "string",
  "plan": "string",
  "device_limit": 0,
  "addons": [
    "string"
  ],
  "binary_delta": {
    "enabled": true,
    "binary_delta": {
      "xdelta_args": {
        "disable_checksum": false,
        "disable_external_decompression": false,
        "compression_level": 6,
        "source_window_size": 0,
        "input_window_size": 0,
        "compression_duplicates_window": 0,
        "instruction_buffer_size": 0
      },
      "timeout": 0
    },
    "binary_delta_limits": {
      "xdelta_args_limits": {
        "compression_level": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "source_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "input_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "compression_duplicates_window": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "instruction_buffer_size": {
          "min": 5,
          "max": 100,
          "default": 10
        }
      },
      "timeout": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "jobs_in_parallel": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "queue_length": {
        "min": 5,
        "max": 100,
        "default": 10
      }
    }
  },
  "sso": true
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/child',
{
  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' => 'Bearer {access-token}'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/child',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.put('https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/child', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/child', 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/tenantadm/tenants/{id}/child");
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{"Bearer {access-token}"},
    }

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

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

PUT /tenants/{id}/child

Update a Tenant associated with a Service Provider Tenant

Body parameter

{
  "name": "string",
  "plan": "string",
  "device_limit": 0,
  "addons": [
    "string"
  ],
  "binary_delta": {
    "enabled": true,
    "binary_delta": {
      "xdelta_args": {
        "disable_checksum": false,
        "disable_external_decompression": false,
        "compression_level": 6,
        "source_window_size": 0,
        "input_window_size": 0,
        "compression_duplicates_window": 0,
        "instruction_buffer_size": 0
      },
      "timeout": 0
    },
    "binary_delta_limits": {
      "xdelta_args_limits": {
        "compression_level": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "source_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "input_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "compression_duplicates_window": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "instruction_buffer_size": {
          "min": 5,
          "max": 100,
          "default": 10
        }
      },
      "timeout": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "jobs_in_parallel": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "queue_length": {
        "min": 5,
        "max": 100,
        "default": 10
      }
    }
  },
  "sso": true
}

Parameters

Name In Type Required Description
id path string true Tenant ID.
body body UpdateChildTenant true Updated Tenant

Example responses

500 Response

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

Responses

Status Meaning Description Schema
204 No Content Tenant updated. None
500 Internal Server Error Internal server error. Error

Activate Account

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/status \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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

const inputBody = '{
  "status": "active"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/tenants/{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' => 'Bearer {access-token}'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/status',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.put('https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/status', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/management/v2/tenantadm/tenants/{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/v2/tenantadm/tenants/{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{"Bearer {access-token}"},
    }

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

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

PUT /tenants/{id}/status

Activate tenant's account.

Changes the given tenant's suspension status to active. The only valid statuses is 'active'.

Body parameter

{
  "status": "active"
}

Parameters

Name In Type Required Description
id path string true Tenant ID.
body body Status true Target suspension status

Example responses

400 Response

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

Responses

Status Meaning Description Schema
202 Accepted Request to activate tenant was accepted. None
400 Bad Request The request body is malformed. See error for details. Error
404 Not Found The tenant was not found. Error
409 Conflict The tenant was suspended. Error
500 Internal Server Error Internal server error. Error

Cancel Account

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/cancel \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/cancel HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "reason": "Reason for cancelling the tenant"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/cancel',
{
  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' => 'Bearer {access-token}'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/cancel',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/cancel', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/cancel', 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/tenantadm/tenants/{id}/cancel");
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{"Bearer {access-token}"},
    }

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

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

POST /tenants/{id}/cancel

Request the cancellation of a tenant

Requests the cancellation of a tenant.

Body parameter

{
  "reason": "Reason for cancelling the tenant"
}

Parameters

Name In Type Required Description
id path string true Tenant ID.
body body CancelRequest true Cancellation request

Example responses

400 Response

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

Responses

Status Meaning Description Schema
202 Accepted Request has been successfully recorded. None
400 Bad Request The request body is malformed. See error for details. Error
404 Not Found The tenant was not found. Error
409 Conflict The tenant is not active. Error
500 Internal Server Error Internal server error. Error

Update Plan

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/plan \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/plan HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "current_plan": "Professional",
  "requested_plan": "Enterprise",
  "current_addons": "troubleshoot",
  "requested_addons": "troubleshoot, configure",
  "user_message": "User message"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/plan',
{
  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' => 'Bearer {access-token}'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/plan',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/plan', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/plan', 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/tenantadm/tenants/{id}/plan");
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{"Bearer {access-token}"},
    }

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

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

POST /tenants/{id}/plan

Request the subscription plan/add-ons change

Request the subscription plan/add-ons change.

Body parameter

{
  "current_plan": "Professional",
  "requested_plan": "Enterprise",
  "current_addons": "troubleshoot",
  "requested_addons": "troubleshoot, configure",
  "user_message": "User message"
}

Parameters

Name In Type Required Description
id path string true Tenant ID.
body body PlanChangeRequest true Plan change request

Example responses

400 Response

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

Responses

Status Meaning Description Schema
202 Accepted Request has been successfully recorded. None
400 Bad Request The request body is malformed. See error for details. Error
404 Not Found The tenant was not found. Error
409 Conflict The tenant is not active. Error
500 Internal Server Error Internal server error. Error

Start Account Upgrade

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/start \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/start HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/start',
{
  method: 'POST',

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/start',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/start', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/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/v2/tenantadm/tenants/{id}/upgrade/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{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

POST /tenants/{id}/upgrade/start

Start the upgrade process of a trial tenant.

Start the upgrade process of a trial tenant.

Parameters

Name In Type Required Description
id path string true Tenant ID.

Example responses

A short tenant descriptor is returned.

{
  "id": "507f191e810c19729de860ea",
  "secret": "TYooMQauvdEDq54NiTphI7jx"
}

400 Response

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

Responses

Status Meaning Description Schema
200 OK A short tenant descriptor is returned. TenantShortInfo
400 Bad Request The request is malformed. Error
500 Internal Server Error Internal server error. Error

Complete Account Upgrade

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/complete \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/complete HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "plan": "os"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/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',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/complete',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/complete', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/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/v2/tenantadm/tenants/{id}/upgrade/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"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

POST /tenants/{id}/upgrade/complete

Complete the upgrade process of a trial tenant to a specified plan.

Complete the upgrade process of a trial tenant to a specified plan.

Body parameter

{
  "plan": "os"
}

Parameters

Name In Type Required Description
id path string true Tenant ID.
body body UpgradeCompleteRequest true Upgrade completion request

Example responses

400 Response

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

Responses

Status Meaning Description Schema
202 Accepted Request to complete the tenant upgrade was successfully processed None
400 Bad Request The request is malformed. Error
500 Internal Server Error Internal server error. Error

Cancel Account Upgrade

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/cancel \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/cancel HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/cancel',
{
  method: 'POST',

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/cancel',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/cancel', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/upgrade/cancel', 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/tenantadm/tenants/{id}/upgrade/cancel");
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{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

POST /tenants/{id}/upgrade/cancel

Cancel the upgrade process of a trial tenant.

Cancel the upgrade process of a trial tenant.

Parameters

Name In Type Required Description
id path string true Tenant ID.

Example responses

400 Response

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

Responses

Status Meaning Description Schema
202 Accepted Request to cancel the tenant upgrade was accepted None
400 Bad Request The request is malformed. Error
500 Internal Server Error Internal server error. Error

Init Tenant Removal

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/remove/start \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/remove/start HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/remove/start',
{
  method: 'POST',

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/remove/start',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/remove/start', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v2/tenantadm/tenants/{id}/remove/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/v2/tenantadm/tenants/{id}/remove/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{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

POST /tenants/{id}/remove/start

Initialize the process of tenant removal.

Start the asynchronous process of removing tenant from the system.

Parameters

Name In Type Required Description
id path string true Tenant ID.

Example responses

400 Response

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

Responses

Status Meaning Description Schema
202 Accepted Request to cancel the tenant upgrade was accepted None
400 Bad Request The request is malformed. Error
500 Internal Server Error Internal server error. Error

Get billing information

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/tenantadm/billing \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/billing',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v2/tenantadm/billing', 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/tenantadm/billing");
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{"Bearer {access-token}"},
    }

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

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

GET /billing

Get billing information, such as the card stored as default payment method in stripe

Example responses

Stripe stored card data is returned.

{
  "card": {
    "brand": "Visa",
    "checks": {
      "address_line1_check": "pass",
      "address_postal_code_check": "pass",
      "cvc_check": "pass"
    },
    "country": "no",
    "description": "",
    "exp_month": 2,
    "exp_year": 2020,
    "fingerprint": "fingerprint",
    "funding": "all",
    "iin": "",
    "issuer": "",
    "last4": "1234",
    "three_d_secure_usage": {
      "supported": true
    },
    "wallet": {
      "dynamic_last4": "6789",
      "type": "visa_checkout"
    }
  }
}

500 Response

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

Responses

Status Meaning Description Schema
200 OK Stripe stored card data is returned. BillingInfo
500 Internal Server Error Internal server error. Error

Get stripe secret

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/tenantadm/billing/secret \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v2/tenantadm/billing/secret HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/billing/secret',
{
  method: 'POST',

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('https://hosted.mender.io/api/management/v2/tenantadm/billing/secret', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v2/tenantadm/billing/secret', 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/tenantadm/billing/secret");
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{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

POST /billing/secret

Get stripe client secret, create if not exist.

Example responses

Stripe client secret is returned.

{
  "secret": "TYooMQauvdEDq54NiTphI7jx"
}

500 Response

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

Responses

Status Meaning Description Schema
200 OK Stripe client secret is returned. CheckoutData
500 Internal Server Error Internal server error. Error

Init Card Update

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/tenantadm/billing/card \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v2/tenantadm/billing/card HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/billing/card',
{
  method: 'POST',

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('https://hosted.mender.io/api/management/v2/tenantadm/billing/card', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v2/tenantadm/billing/card', 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/tenantadm/billing/card");
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{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

POST /billing/card

Generate a Stripe setup intent for collecting updated CC details via the UI.

Example responses

Stripe setup intent id and secret is returned.

{
  "intent_id": "seti_1HXHVn2eZvKYlo2CT3XEEjKB",
  "secret": "TYooMQauvdEDq54NiTphI7jx"
}

401 Response

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

Responses

Status Meaning Description Schema
200 OK Stripe setup intent id and secret is returned. CardSetupData
401 Unauthorized Unauthorized. Error
409 Conflict Tenant is in invalid state; see error for details. Error
500 Internal Server Error Internal server error. Error

Confirm Card Update

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/tenantadm/billing/card/{id}/confirm \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v2/tenantadm/billing/card/{id}/confirm HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/billing/card/{id}/confirm',
{
  method: 'POST',

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v2/tenantadm/billing/card/{id}/confirm',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('https://hosted.mender.io/api/management/v2/tenantadm/billing/card/{id}/confirm', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v2/tenantadm/billing/card/{id}/confirm', 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/tenantadm/billing/card/{id}/confirm");
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{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

POST /billing/card/{id}/confirm

Save the credit card collected using the given intent as the default card.

Parameters

Name In Type Required Description
id path string true Setup intent ID obtained from POST /card.

Example responses

401 Response

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

Responses

Status Meaning Description Schema
204 No Content New credit card is saved as the default one. None
401 Unauthorized Unauthorized. Error
404 Not Found Intent not found. Error
409 Conflict Setup intent is in invalid state; see error for details. Error
500 Internal Server Error Internal server error. Error

Contact Support

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/tenantadm/contact/support \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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

const inputBody = '{
  "subject": "Subscription change request",
  "body": "Requested addons: Troubleshoot, Configure"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/tenantadm/contact/support',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

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

r = requests.post('https://hosted.mender.io/api/management/v2/tenantadm/contact/support', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v2/tenantadm/contact/support', 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/tenantadm/contact/support");
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{"Bearer {access-token}"},
    }

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

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

POST /contact/support

Send message to Mender support

The message is free form; internally it will be auto-decorated with important metadata (organization id/name, user id/name, etc.).

Body parameter

{
  "subject": "Subscription change request",
  "body": "Requested addons: Troubleshoot, Configure"
}

Parameters

Name In Type Required Description
body body SupportRequest true Support request data

Example responses

400 Response

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

Responses

Status Meaning Description Schema
202 Accepted Message accepted. None
400 Bad Request Message invalid; see error for details. Error
401 Unauthorized Unauthorized. Error
500 Internal Server Error Internal server error. Error

Schemas

TenantShortInfo

{
  "id": "652fee57675f5d647b92fef5",
  "intent_id": "seti_1HXHVn2eZvKYlo2CT3XEEjKB",
  "secret": "TYooMQauvdEDq54NiTphI7jx"
}

Tenant short info.

Properties
Name Type Required Description
id string true Tenant ID.
intent_id string false Stripe Intent ID.
secret string true Stripe client secret.

BillingInfo

{
  "card": {
    "brand": "Visa",
    "checks": {
      "address_line1_check": "pass",
      "address_postal_code_check": "pass",
      "cvc_check": "pass"
    },
    "country": "no",
    "description": "",
    "exp_month": 2,
    "exp_year": 2020,
    "fingerprint": "fingerprint",
    "funding": "all",
    "iin": "",
    "issuer": "",
    "last4": "1234",
    "three_d_secure_usage": {
      "supported": true
    },
    "wallet": {
      "dynamic_last4": "6789",
      "type": "visa_checkout"
    }
  },
  "subscription": {
    "id": "sub_36VrPHS2vVxJMq",
    "object": "subscription",
    "application_fee_percent": null,
    "billing_cycle_anchor": 1387222772,
    "billing_thresholds": null,
    "cancel_at": null,
    "cancel_at_period_end": false,
    "canceled_at": 1445989053,
    "collection_method": "charge_automatically",
    "created": 1386790772,
    "current_period_end": 1447702772,
    "current_period_start": 1444678772,
    "customer": "cus_36Akh5CetFGg9T",
    "days_until_due": null,
    "default_payment_method": null,
    "default_source": null,
    "default_tax_rates": [],
    "discount": null,
    "ended_at": 1445989053,
    "items": {
      "object": "list",
      "data": [
        {
          "id": "si_18SfBn2eZvKYlo2C1fwOImYF",
          "object": "subscription_item",
          "billing_thresholds": null,
          "created": 1386790772,
          "metadata": {},
          "price": {
            "id": "40",
            "object": "price",
            "active": true,
            "billing_scheme": "per_unit",
            "created": 1386694689,
            "currency": "usd",
            "livemode": false,
            "lookup_key": null,
            "metadata": {
              "charset": "utf-8",
              "content": "40"
            },
            "nickname": null,
            "product": "prod_BTcfj5EqyqxDVn",
            "recurring": {
              "aggregate_usage": null,
              "interval": "week",
              "interval_count": 5,
              "usage_type": "licensed"
            },
            "tiers_mode": null,
            "transform_quantity": null,
            "type": "recurring",
            "unit_amount": 5465,
            "unit_amount_decimal": "5465"
          },
          "quantity": 1,
          "subscription": "sub_36VrPHS2vVxJMq",
          "tax_rates": []
        }
      ],
      "has_more": false,
      "url": "/v1/subscription_items?subscription=sub_36VrPHS2vVxJMq"
    },
    "latest_invoice": null,
    "livemode": false,
    "metadata": {},
    "next_pending_invoice_item_invoice": null,
    "pause_collection": null,
    "pending_invoice_item_interval": null,
    "pending_setup_intent": null,
    "pending_update": null,
    "schedule": null,
    "start_date": 1386790772,
    "status": "canceled",
    "transfer_data": null,
    "trial_end": 1387222772,
    "trial_start": 1386790772
  }
}

Billing related data, such as credit card information and next billing date

Properties
Name Type Required Description
card CardData false Card information stored in Stripe. The full type description is available at "https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.yaml#/components/schemas/payment_method_card"
subscription SubscriptionData false Subscription information stored in Stripe. The full type description is available at "https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.yaml#/components/schemas/subscription"

CardData

{
  "brand": "string",
  "checks": {
    "address_line1_check": "string",
    "address_postal_code_check": "string",
    "cvc_check": "string"
  },
  "country": "string",
  "exp_month": 0,
  "exp_year": 0,
  "fingerprint": "string",
  "funding": "string",
  "last4": "string",
  "three_d_secure_usage": {
    "supported": true
  },
  "wallet": {
    "dynamic_last4": "string",
    "type": "string"
  }
}

Card information stored in Stripe. The full type description is available at "https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.yaml#/components/schemas/payment_method_card"

Properties
Name Type Required Description
brand string false Card brand. Can be amex, diners, discover, jcb, mastercard, unionpay, visa, or unknown.
checks object false Checks on Card address and CVC if provided.
» address_line1_check string false
» address_postal_code_check string false
» cvc_check string false
country string false Two-letter ISO code representing the country of the card. You could use this attribute to get a sense of the international breakdown of cards you've collected.
exp_month integer false Two-digit number representing the card's expiration month.
exp_year integer false Four-digit number representing the card's expiration year.
fingerprint string false Uniquely identifies this particular card number. You can use this attribute to check whether two customers who’ve signed up with you are using the same card number,for example. For payment methods that tokenize card information (Apple Pay, Google Pay), the tokenized number might be provided instead of the underlying card number.
funding string false Card funding type. Can be credit, debit, prepaid, or unknown.
last4 string false The last four digits of the card.
three_d_secure_usage object false Contains details on how this Card maybe be used for 3D Secure authentication.
» supported boolean false
wallet object false If this Card is part of a card wallet, this contains the details of the card wallet.
» dynamic_last4 string false
» type string false

SubscriptionData

{
  "id": "sub_36VrPHS2vVxJMq",
  "object": "subscription",
  "application_fee_percent": null,
  "billing_cycle_anchor": 1387222772,
  "billing_thresholds": null,
  "cancel_at": null,
  "cancel_at_period_end": false,
  "canceled_at": 1445989053,
  "collection_method": "charge_automatically",
  "created": 1386790772,
  "current_period_end": 1447702772,
  "current_period_start": 1444678772,
  "customer": "cus_36Akh5CetFGg9T",
  "days_until_due": null,
  "default_payment_method": null,
  "default_source": null,
  "default_tax_rates": [],
  "discount": null,
  "ended_at": 1445989053,
  "items": {
    "object": "list",
    "data": [
      {
        "id": "si_18SfBn2eZvKYlo2C1fwOImYF",
        "object": "subscription_item",
        "billing_thresholds": null,
        "created": 1386790772,
        "metadata": {},
        "price": {
          "id": "40",
          "object": "price",
          "active": true,
          "billing_scheme": "per_unit",
          "created": 1386694689,
          "currency": "usd",
          "livemode": false,
          "lookup_key": null,
          "metadata": {
            "charset": "utf-8",
            "content": "40"
          },
          "nickname": null,
          "product": "prod_BTcfj5EqyqxDVn",
          "recurring": {
            "aggregate_usage": null,
            "interval": "week",
            "interval_count": 5,
            "usage_type": "licensed"
          },
          "tiers_mode": null,
          "transform_quantity": null,
          "type": "recurring",
          "unit_amount": 5465,
          "unit_amount_decimal": "5465"
        },
        "quantity": 1,
        "subscription": "sub_36VrPHS2vVxJMq",
        "tax_rates": []
      }
    ],
    "has_more": false,
    "url": "/v1/subscription_items?subscription=sub_36VrPHS2vVxJMq"
  },
  "latest_invoice": null,
  "livemode": false,
  "metadata": {},
  "next_pending_invoice_item_invoice": null,
  "pause_collection": null,
  "pending_invoice_item_interval": null,
  "pending_setup_intent": null,
  "pending_update": null,
  "schedule": null,
  "start_date": 1386790772,
  "status": "canceled",
  "transfer_data": null,
  "trial_end": 1387222772,
  "trial_start": 1386790772
}

Subscription information stored in Stripe. The full type description is available at "https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.yaml#/components/schemas/subscription"

Properties

None

CheckoutData

{
  "secret": "TYooMQauvdEDq54NiTphI7jx"
}

Checkout data.

Properties
Name Type Required Description
secret string true Stripe client secret.

CardSetupData

{
  "intent_id": "seti_1HXHVn2eZvKYlo2CT3XEEjKB",
  "secret": "TYooMQauvdEDq54NiTphI7jx"
}

Stripe setup intent data.

Properties
Name Type Required Description
intent_id string true Setup intent id.
secret string true Setup intent secret.

Status

{
  "status": "active"
}

Status of a tenant account.

Properties
Name Type Required Description
status string true
Enumerated Values
Property Value
status active
status inactive
status suspended

CancelRequest

{
  "reason": "Reason for cancelling the tenant"
}

Cancellation request of a tenant account.

Properties
Name Type Required Description
reason string true

PlanChangeRequest

{
  "current_plan": "Professional",
  "requested_plan": "Enterprise",
  "current_addons": "troubleshoot",
  "requested_addons": "troubleshoot, configure",
  "user_message": "User message"
}

Plan/add-on change request of a tenant account.

Properties
Name Type Required Description
current_plan string false
requested_plan string false
current_addons string false
requested_addons string false
user_message string false

UpgradeCompleteRequest

{
  "plan": "os"
}

Upgrade a trial tenant to a given plan.

Properties
Name Type Required Description
plan string true customer plan
Enumerated Values
Property Value
plan os
plan professional
plan enterprise

SupportRequest

{
  "subject": "Subscription change request",
  "body": "Requested addons: Troubleshoot, Configure"
}

Contact support request.

Properties
Name Type Required Description
subject string true Message subject.
body string true Message body.

NewTenant

{
  "name": "string",
  "admin": {
    "email": "string",
    "password": "string",
    "login": {}
  },
  "plan": "string",
  "device_limit": 0,
  "addons": [
    "string"
  ],
  "binary_delta": {
    "enabled": true,
    "binary_delta": {
      "xdelta_args": {
        "disable_checksum": false,
        "disable_external_decompression": false,
        "compression_level": 6,
        "source_window_size": 0,
        "input_window_size": 0,
        "compression_duplicates_window": 0,
        "instruction_buffer_size": 0
      },
      "timeout": 0
    },
    "binary_delta_limits": {
      "xdelta_args_limits": {
        "compression_level": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "source_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "input_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "compression_duplicates_window": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "instruction_buffer_size": {
          "min": 5,
          "max": 100,
          "default": 10
        }
      },
      "timeout": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "jobs_in_parallel": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "queue_length": {
        "min": 5,
        "max": 100,
        "default": 10
      }
    }
  },
  "sso": true
}

New Tenant

Properties
Name Type Required Description
name string false Name of the tenant.
admin object false
» email string false Email address of the admin user
» password string false Password of the admin user, must be provided if not using SSO
» login object false Alternative SSO login schemes, must be provided if password is empty
plan string false Plan for the tenant, e.g.: os, professional, enterprise.
device_limit integer false Device limit for the tenant.
addons [string] false List of add-ons to enable for the tenant, e.g.: troubleshoot, configure, monitor.
binary_delta DeltaConfiguration false Delta configuration options.
sso boolean false Enable SSO for the tenant.

UpdateChildTenant

{
  "name": "string",
  "plan": "string",
  "device_limit": 0,
  "addons": [
    "string"
  ],
  "binary_delta": {
    "enabled": true,
    "binary_delta": {
      "xdelta_args": {
        "disable_checksum": false,
        "disable_external_decompression": false,
        "compression_level": 6,
        "source_window_size": 0,
        "input_window_size": 0,
        "compression_duplicates_window": 0,
        "instruction_buffer_size": 0
      },
      "timeout": 0
    },
    "binary_delta_limits": {
      "xdelta_args_limits": {
        "compression_level": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "source_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "input_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "compression_duplicates_window": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "instruction_buffer_size": {
          "min": 5,
          "max": 100,
          "default": 10
        }
      },
      "timeout": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "jobs_in_parallel": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "queue_length": {
        "min": 5,
        "max": 100,
        "default": 10
      }
    }
  },
  "sso": true
}

Update Tenant

Properties
Name Type Required Description
name string false Name of the tenant.
plan string false Plan for the tenant, e.g.: os, professional, enterprise.
device_limit integer false Device limit for the tenant.
addons [string] false List of add-ons to enable for the tenant, e.g.: troubleshoot, configure, monitor.
binary_delta DeltaConfiguration false Delta configuration options.
sso boolean false Enable SSO for the tenant.

BinaryDeltaConfiguration

{
  "xdelta_args": {
    "disable_checksum": false,
    "disable_external_decompression": false,
    "compression_level": 6,
    "source_window_size": 0,
    "input_window_size": 0,
    "compression_duplicates_window": 0,
    "instruction_buffer_size": 0
  },
  "timeout": 0
}

The mender-binary-delta-generator configuration options.

Properties
Name Type Required Description
xdelta_args XDeltaArgs false xdelta3 arguments. Please refer to the xdelta3 documentation
for a detailed description of the different options.
timeout number(integer) false Delta generation job timeout in seconds.

BinaryDeltaLimits

{
  "xdelta_args_limits": {
    "compression_level": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "source_window_size": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "input_window_size": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "compression_duplicates_window": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "instruction_buffer_size": {
      "min": 5,
      "max": 100,
      "default": 10
    }
  },
  "timeout": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "jobs_in_parallel": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "queue_length": {
    "min": 5,
    "max": 100,
    "default": 10
  }
}

The mender-binary-delta-generator configuration limits.

Properties
Name Type Required Description
xdelta_args_limits XDeltaArgsLimits false Limits for arguments which will be passed to xdelta3.
Please refer to the xdelta3 documentation
for a detailed description of the different options.
timeout Limit false Limit descriptor.
jobs_in_parallel Limit false Limit descriptor.
queue_length Limit false Limit descriptor.

DeltaConfiguration

{
  "enabled": true,
  "binary_delta": {
    "xdelta_args": {
      "disable_checksum": false,
      "disable_external_decompression": false,
      "compression_level": 6,
      "source_window_size": 0,
      "input_window_size": 0,
      "compression_duplicates_window": 0,
      "instruction_buffer_size": 0
    },
    "timeout": 0
  },
  "binary_delta_limits": {
    "xdelta_args_limits": {
      "compression_level": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "source_window_size": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "input_window_size": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "compression_duplicates_window": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "instruction_buffer_size": {
        "min": 5,
        "max": 100,
        "default": 10
      }
    },
    "timeout": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "jobs_in_parallel": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "queue_length": {
      "min": 5,
      "max": 100,
      "default": 10
    }
  }
}

Delta configuration options.

Properties
Name Type Required Description
enabled boolean false
binary_delta BinaryDeltaConfiguration false The mender-binary-delta-generator configuration options.
binary_delta_limits BinaryDeltaLimits false The mender-binary-delta-generator configuration limits.

XDeltaArgs

{
  "disable_checksum": false,
  "disable_external_decompression": false,
  "compression_level": 6,
  "source_window_size": 0,
  "input_window_size": 0,
  "compression_duplicates_window": 0,
  "instruction_buffer_size": 0
}

xdelta3 arguments. Please refer to the xdelta3 documentation for a detailed description of the different options.

Properties
Name Type Required Description
disable_checksum boolean false Disables checksum
disable_external_decompression boolean false Disable external decompression
compression_level number(integer) false Compression level
source_window_size number(integer) false Source window size
input_window_size number(integer) false Input window size
compression_duplicates_window number(integer) false Compression duplicates window
instruction_buffer_size number(integer) false Instruction buffer size

XDeltaArgsLimits

{
  "compression_level": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "source_window_size": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "input_window_size": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "compression_duplicates_window": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "instruction_buffer_size": {
    "min": 5,
    "max": 100,
    "default": 10
  }
}

Limits for arguments which will be passed to xdelta3. Please refer to the xdelta3 documentation for a detailed description of the different options.

Properties
Name Type Required Description
compression_level Limit false Limit descriptor.
source_window_size Limit false Limit descriptor.
input_window_size Limit false Limit descriptor.
compression_duplicates_window Limit false Limit descriptor.
instruction_buffer_size Limit false Limit descriptor.

Limit

{
  "min": 5,
  "max": 100,
  "default": 10
}

Limit descriptor.

Properties
Name Type Required Description
min number false Minimum value.
max number false Maximum value.
default number false Default value.

Tenant

{
  "id": "507f191e810c19729de860ea",
  "name": "Acme",
  "tenant_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODcwNTU3MzUsImp0aSI6IjM5MTJiZDNmLWVjMTEtNDgwNy05MmE4LTBkOTVjMWFmYjU1NCIsImlzcyI6Ik1lbmRlciIsInN1YiI6ImQ0NTljOTFmZDkzMWFkOGM0ZDk4ZGIyZjdlZjU3NjYxNDI3NDJiZDMyMzM0ZjIyNjYyZTNiNjE5YmRiZTJhNTYifQ.iY2XuyuDOHW9ilPPeeHuwmz9A-6asDqdfy3mCjXuODns1SshbuH_XXFPa7s2PpXCMkhEHB82nLEjwcSO7gTIz1uqzjyGufVbXlOiZqPrCXUm4DKvhSgANiVKfkw_JvD1w-V0jyctBcrUifIhqhRlhXNAJh3c5XAMzxe2kwt9t3JW5bXiXroc64gXdv0gnX-o7YgdrFfau3rAaMFinKqHzACmeE5YhEVF9eQPJQ99U0PO6tVCcG39O-vtt51ClWh3BVeeQrHcr5eWQZWFMHThdeoRitLwvsN8wzrEKUoL9q9SlFnu4uGJkfOfTuiafgF1pJ-UBDYdBdV4sV9626PdHQ",
  "status": "active"
}

Tenant descriptor.

Properties
Name Type Required Description
id string true Tenant ID.
name string true Name of the tenant's organization.
tenant_token string true Currently used tenant token.
status string false Status of the tenant account.
api_limits TenantApiLimits false API usage quota and burst limit definitions for a tenant - per API type.
addons [Addon] false [Mender addon definition.]
Enumerated Values
Property Value
status active
status suspended

TenantApiLimits

{
  "management": {
    "quota": {
      "max_calls": 100,
      "interval_sec": 60
    }
  },
  "devices": {
    "quota": {
      "max_calls": 1000,
      "interval_sec": 60
    },
    "bursts": [
      {
        "action": "PATCH",
        "uri": "/api/devices/v1/inventory/device/attributes",
        "min_interval_sec": 10
      },
      {
        "action": "POST",
        "uri": "/api/devices/v1/deployments/device/deployments/next",
        "min_interval_sec": 60
      }
    ]
  }
}

API usage quota and burst limit definitions for a tenant - per API type.

Properties
Name Type Required Description
management ApiLimits false Usage quota and burst limit definitions for an API type.
devices ApiLimits false Usage quota and burst limit definitions for an API type.

Addon

{
  "name": "troubleshoot",
  "enabled": true
}

Mender addon definition.

Properties
Name Type Required Description
name string false Name of the addon (one of ['configure', 'troubleshoot']).
enabled boolean false Enabled/disabled flag.

ApiBurst

{
  "action": "PATCH",
  "uri": "/api/devices/v1/inventory/device/attributes",
  "min_interval_sec": 10
}

API burst limit definition.

Properties
Name Type Required Description
action string false HTTP verb.
uri string false URI of the resource subject to the limit.
min_interval_sec integer false Minimum allowed interval, in seconds, between subsequent calls to 'action' on 'uri' (10 = one call every 10 seconds, etc.)

ApiQuota

{
  "max_calls": 100,
  "interval_sec": 3600
}

API usage quota definition.

Properties
Name Type Required Description
max_calls integer false Maximum allowed number of calls within 'interval'.
interval_sec integer false Interval definition, in seconds (60 = 1 minute, 3600 = 1 hour, etc.).

ApiLimits

{
  "bursts": [
    {
      "action": "PATCH",
      "uri": "/api/devices/v1/inventory/device/attributes",
      "min_interval_sec": 10
    },
    {
      "action": "POST",
      "uri": "/api/devices/v1/deployments/device/deployments/next",
      "min_interval_sec": 60
    }
  ],
  "quota": {
    "max_calls": 100,
    "interval_sec": 60
  }
}

Usage quota and burst limit definitions for an API type.

Properties
Name Type Required Description
bursts [ApiBurst] false Collection of api burst limit definitions over specified API resources.
quota ApiQuota false API usage quota definition.

Error

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

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.

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' \
  -H 'Authorization: Basic {access-token}'

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 = '{
  "no_expiry": true,
  "token2fa": "012234"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/jwt',
  'Authorization':'Basic {access-token}'
};

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',
  'Authorization' => 'Basic {access-token}'
}

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',
  'Authorization': 'Basic {access-token}'
}

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',
    'Authorization' => 'Basic {access-token}',
);

$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"},
        "Authorization": []string{"Basic {access-token}"},
    }

    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

{
  "no_expiry": true,
  "token2fa": "012234"
}

Parameters

Name In Type Required Description
body body LoginOptions false Log in options

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 with content type application/jwt.

The JWT is signed with the API's private key ('RS256' signing algorithm), and contains the following standard claims:

If the login process requires SSO, the content type will be application/json and the body will contain a JSON document containing the following properties:

Example response: {"id": "1a97b53f-9b84-5048-8874-df01f4f58f78", "kind": "sso/saml"}|string| |400|Bad Request|Bad request, see error message for details.|Error| |401|Unauthorized|The user is not authorized. There are two possible scenarios for that:

Code samples

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

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


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

fetch('https://hosted.mender.io/api/management/v1/useradm/auth/magic/{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'
}

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

p JSON.parse(result)

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

r = requests.get('https://hosted.mender.io/api/management/v1/useradm/auth/magic/{id}', 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/auth/magic/{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/auth/magic/{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"},
    }

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

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

GET /auth/magic/{id}

Parses uuid referencing a one-time use, short lived magic token and logs a user in automatically

Name In Type Required Description
id path string(uuid) true

Example responses

401 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}
Status Meaning Description Schema
307 Temporary Redirect Authentication successful - a new JWT is issued and set as a cookie and
a user redirect to the UI is returned. None
401 Unauthorized The user is not authorized. There are two possible scenarios for that:

Submit assertion data

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/useradm/auth/sso/{id}/acs \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept: application/json'

POST https://hosted.mender.io/api/management/v1/useradm/auth/sso/{id}/acs HTTP/1.1
Host: hosted.mender.io
Content-Type: application/x-www-form-urlencoded
Accept: application/json

const inputBody = '{
  "SAMLResponse": "string"
}';
const headers = {
  'Content-Type':'application/x-www-form-urlencoded',
  'Accept':'application/json'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/auth/sso/{id}/acs',
{
  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/x-www-form-urlencoded',
  'Accept' => 'application/json'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v1/useradm/auth/sso/{id}/acs',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Accept': 'application/json'
}

r = requests.post('https://hosted.mender.io/api/management/v1/useradm/auth/sso/{id}/acs', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/x-www-form-urlencoded',
    '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/sso/{id}/acs', 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/sso/{id}/acs");
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/x-www-form-urlencoded"},
        "Accept": []string{"application/json"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v1/useradm/auth/sso/{id}/acs", data)
    req.Header = headers

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

POST /auth/sso/{id}/acs

Parses signed and encrypted SAML SSO assertion data

Body parameter

SAMLResponse: string

Parameters

Name In Type Required Description
id path string(uuid) true
body body object true
» SAMLResponse body string true Base64 encoded XML assertion data.

Example responses

400 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
400 Bad Request The request body is malformed. Error
403 Forbidden Request forbidden, possibly due to the feature not being available in the current Mender plan. Error
404 Not Found Resource has not been found. Error
415 Unsupported Media Type Endpoint does not support the provided Content-Type. Error
422 Unprocessable Entity The metadata has not been uploaded yet. Error
500 Internal Server Error Internal server error. Error

Login via given Identity Provider

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/useradm/auth/sso/{id}/login \
  -H 'Accept: application/json'

GET https://hosted.mender.io/api/management/v1/useradm/auth/sso/{id}/login HTTP/1.1
Host: hosted.mender.io
Accept: application/json


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

fetch('https://hosted.mender.io/api/management/v1/useradm/auth/sso/{id}/login',
{
  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/auth/sso/{id}/login',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('https://hosted.mender.io/api/management/v1/useradm/auth/sso/{id}/login', 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/auth/sso/{id}/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/sso/{id}/login");
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/auth/sso/{id}/login", data)
    req.Header = headers

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

GET /auth/sso/{id}/login

Sets cookies and redirects to the Identity Provider for login

Parameters

Name In Type Required Description
id path string(uuid) true

Example responses

302 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
302 Found The request body is malformed. Error
404 Not Found Resource has not been found. Error
422 Unprocessable Entity The metadata has not been uploaded yet. Error

Logout

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/useradm/auth/logout \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v1/useradm/auth/logout HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/auth/logout',
{
  method: 'POST',

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/logout', 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/logout");
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{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

POST /auth/logout

Log out from Mender

Invalidates the JWT token of the current user.

Example responses

400 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
202 Accepted Request has been accepted and the JWT token has been invalidated. None
400 Bad Request Bad request, see error message for details. Error
401 Unauthorized Unauthorized. Error
500 Internal Server Error Internal server error. Error

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
429 Too Many Requests Too many requests. 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

Initiate Email Verification Request

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/useradm/auth/verify-email/start \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST https://hosted.mender.io/api/management/v1/useradm/auth/verify-email/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/verify-email/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/verify-email/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/verify-email/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/verify-email/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/verify-email/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/verify-email/start", data)
    req.Header = headers

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

POST /auth/verify-email/start

Initiate an Email Verification request based on the provided email address

Starts an Email Verification request, sending an email to the user containing a unique, time-based hash which can be used to verify the email address of the user.

Body parameter

{
  "email": "user@mender.io"
}

Parameters

Name In Type Required Description
body body EmailVerificationRequest false Email Verification request, it includes the email address of the user.
Detailed descriptions

body: Email Verification 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 Email Verification

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/useradm/auth/verify-email/complete \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST https://hosted.mender.io/api/management/v1/useradm/auth/verify-email/complete HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "secret": "16fd2706-8baf-433b-82eb-8c7fada847da"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/auth/verify-email/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/verify-email/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/verify-email/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/verify-email/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/verify-email/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/verify-email/complete", data)
    req.Header = headers

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

POST /auth/verify-email/complete

Complete an Email Verification procedure

Complete an Email Verification procedure initiated by the /auth/verify-email/start end-point. Caller provides the secret hash received by email.

Body parameter

{
  "secret": "16fd2706-8baf-433b-82eb-8c7fada847da"
}

Parameters

Name In Type Required Description
body body EmailVerificationCompletion false Email Verification request, it includes the secret hash received by email.
Detailed descriptions

body: Email Verification request, it includes the secret hash received by email.

Example responses

400 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content The email address has been verified. None
400 Bad Request The request body is malformed. Error
500 Internal Server Error Internal server error. Error

Verify Plan

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/useradm/auth/plan-verify \
  -H 'Accept: application/json' \
  -H 'X-Mender-Required-Minimal-Plan: string' \
  -H 'X-Mender-Required-Addon: string' \
  -H 'Authorization: Basic {access-token}'

POST https://hosted.mender.io/api/management/v1/useradm/auth/plan-verify HTTP/1.1
Host: hosted.mender.io
Accept: application/json
X-Mender-Required-Minimal-Plan: string
X-Mender-Required-Addon: string


const headers = {
  'Accept':'application/json',
  'X-Mender-Required-Minimal-Plan':'string',
  'X-Mender-Required-Addon':'string',
  'Authorization':'Basic {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/auth/plan-verify',
{
  method: 'POST',

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'X-Mender-Required-Minimal-Plan' => 'string',
  'X-Mender-Required-Addon' => 'string',
  'Authorization' => 'Basic {access-token}'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v1/useradm/auth/plan-verify',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'X-Mender-Required-Minimal-Plan': 'string',
  'X-Mender-Required-Addon': 'string',
  'Authorization': 'Basic {access-token}'
}

r = requests.post('https://hosted.mender.io/api/management/v1/useradm/auth/plan-verify', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'X-Mender-Required-Minimal-Plan' => 'string',
    'X-Mender-Required-Addon' => 'string',
    'Authorization' => 'Basic {access-token}',
);

$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/plan-verify', 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/plan-verify");
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{
        "Accept": []string{"application/json"},
        "X-Mender-Required-Minimal-Plan": []string{"string"},
        "X-Mender-Required-Addon": []string{"string"},
        "Authorization": []string{"Basic {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v1/useradm/auth/plan-verify", data)
    req.Header = headers

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

POST /auth/plan-verify

Check if the user has given or superior pricing plan associated

Checks if user is in the given plan, or a superior one

Parameters

Name In Type Required Description
X-Mender-Required-Minimal-Plan header string true Required minimal plan to complete the request
X-Mender-Required-Addon header string true Required add-on to complete the request
Detailed descriptions

X-Mender-Required-Minimal-Plan: Required minimal plan to complete the request

X-Mender-Required-Addon: Required add-on to complete the request

Example responses

401 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
202 Accepted The required minimal plan matches the user plan None
401 Unauthorized The user authentication failed Error
403 Forbidden The required minimal plan doesn't match the user plan Error
500 Internal Server Error Unexpected 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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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. *

Parameters

Name In Type Required Description
id query string false Limit result by user ID, can be repeated to include multiple users in the query.
email query string false Limit result by user email, can be repeated to include multiple users in the query.
created_after query integer false Filter users created after timestamp (UNIX timestamp).
created_before query integer false Filter users created before timestamp (UNIX timestamp).
updated_after query integer false Filter users updated after timestamp (UNIX timestamp).
updated_before query integer false Filter users updated before timestamp (UNIX timestamp).
Detailed descriptions

id: Limit result by user ID, can be repeated to include multiple users in the query.

email: Limit result by user email, can be repeated to include multiple users in the query.

created_after: Filter users created after timestamp (UNIX timestamp).

created_before: Filter users created before timestamp (UNIX timestamp).

updated_after: Filter users updated after timestamp (UNIX timestamp).

updated_before: Filter users updated before timestamp (UNIX timestamp).

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.
» login_ts string(date-time) false Timestamp the of last successful login.
» verified boolean false Indicates if the user's email address has been verified.
» tfa_status string false User Two Factor Authentication status.
» roles [string] false List of user roles.
»» ListOfRoles string false Role name
» send_reset_password boolean false Flag indicating wether to trigger password reset on user creation.

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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, password is too short, current password doesn't match or limit on maximum number of users has been exceeded.

It is possible that the user with the given email address exists in a different organization. In this case Mender server will also produce an error because the email address has to be unique across all organizations.|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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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"
  ],
  "password": "new password",
  "current_password": "old password"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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"
  ],
  "password": "new password",
  "current_password": "old password"
}

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, the password is too short
or the user is trying to modify another user's password. 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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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

Show Own User Data

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/useradm/users/me \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/users/me',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/me', 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/me");
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{"Bearer {access-token}"},
    }

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

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

GET /users/me

Get user information

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",
  "tenant_id": "84430f18-d464-5194-b8ef-b1a15161bb4c",
  "tenant_ids": [
    "84430f18-d464-5194-b8ef-b1a15161bb4c",
    "2c481d66-4bd0-43ad-a8b9-61503611c745"
  ]
}

Responses

Status Meaning Description Schema
200 OK Successful response - a user information is returned. UserWithTenantInfo
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 Own User Data

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v1/useradm/users/me \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

PUT https://hosted.mender.io/api/management/v1/useradm/users/me HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "email": "new_email@acme.com",
  "password": "new password",
  "current_password": "old password"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/users/me',
{
  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' => 'Bearer {access-token}'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v1/useradm/users/me',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.put('https://hosted.mender.io/api/management/v1/useradm/users/me', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/me', 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/me");
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{"Bearer {access-token}"},
    }

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

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

PUT /users/me

Update own user information

Body parameter

{
  "email": "new_email@acme.com",
  "password": "new password",
  "current_password": "old password"
}

Parameters

Name In Type Required Description
body body OwnUserUpdate 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 the password is too short. Error
500 Internal Server Error Internal server error. Error

Enable 2FA

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/useradm/users/{id}/2fa/enable \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v1/useradm/users/{id}/2fa/enable HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/users/{id}/2fa/enable',
{
  method: 'POST',

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v1/useradm/users/{id}/2fa/enable',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('https://hosted.mender.io/api/management/v1/useradm/users/{id}/2fa/enable', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/{id}/2fa/enable', 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}/2fa/enable");
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{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v1/useradm/users/{id}/2fa/enable", data)
    req.Header = headers

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

POST /users/{id}/2fa/enable

Enable 2FA authentication

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 User id (use 'me' for authenticated user).

Example responses

400 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK 2FA is enabled. None
400 Bad Request Operation is invalid, see error message. Error
401 Unauthorized The user cannot be granted authentication. Error
403 Forbidden Forbidden. Error
404 Not Found The user was not found. Error
500 Internal Server Error Internal server error. Error

Disable 2FA

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/useradm/users/{id}/2fa/disable \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v1/useradm/users/{id}/2fa/disable HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/users/{id}/2fa/disable',
{
  method: 'POST',

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://hosted.mender.io/api/management/v1/useradm/users/{id}/2fa/disable',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('https://hosted.mender.io/api/management/v1/useradm/users/{id}/2fa/disable', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/{id}/2fa/disable', 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}/2fa/disable");
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{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v1/useradm/users/{id}/2fa/disable", data)
    req.Header = headers

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

POST /users/{id}/2fa/disable

Disable 2FA authentication

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 User id (use 'me' for authenticated user).

Example responses

400 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK 2FA is disabled. None
400 Bad Request Operation is invalid, see error message. Error
401 Unauthorized The user cannot be granted authentication. Error
403 Forbidden Forbidden. Error
404 Not Found The user was not found. Error
500 Internal Server Error Internal server error. Error

Assign Tenants

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/useradm/users/{id}/assign \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v1/useradm/users/{id}/assign HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "tenant_ids": [
    "65c76fd6e15517b2f0fbfdf1",
    "65c76fda5e6177ca400a9d4d"
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/users/{id}/assign',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

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

r = requests.post('https://hosted.mender.io/api/management/v1/useradm/users/{id}/assign', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/{id}/assign', 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}/assign");
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{"Bearer {access-token}"},
    }

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

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

POST /users/{id}/assign

Assign tenants to a given user

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

Body parameter

{
  "tenant_ids": [
    "65c76fd6e15517b2f0fbfdf1",
    "65c76fda5e6177ca400a9d4d"
  ]
}

Parameters

Name In Type Required Description
id path string true User id to assign.
body body TenantIdsData true tenantIdsData.

Example responses

400 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK User assigned. None
400 Bad Request Operation is invalid, see error message. Error
401 Unauthorized The user cannot be granted authentication. Error
403 Forbidden Forbidden. Error
404 Not Found The user was not found. 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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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 endpoint is deprecated. Please use /api/management/v2/useradm/roles togheter with /api/management/v2/useradm/permission_sets instead.

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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 endpoint is deprecated. Please use /api/management/v2/useradm/roles togheter with /api/management/v2/useradm/permission_sets instead.

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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 endpoint is deprecated. Please use /api/management/v2/useradm/roles/{id} togheter with /api/management/v2/useradm/permission_sets/{id} instead.

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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 endpoint is deprecated. Please use /api/management/v2/useradm/roles/{id} togheter with /api/management/v2/useradm/permission_sets/{id} instead.

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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 endpoint is deprecated. Please use /api/management/v2/useradm/roles/{id} togheter with /api/management/v2/useradm/permission_sets/{id} instead.

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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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: Bearer {access-token}'

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':'Bearer {access-token}'
};

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' => 'Bearer {access-token}'
}

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': 'Bearer {access-token}'
}

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' => 'Bearer {access-token}',
);

$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{"Bearer {access-token}"},
    }

    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
403 Forbidden The user has no access to authentication settings because of unverified email address. Error
500 Internal Server Error Internal server error. Error

Show My User Settings

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/useradm/settings/me \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/settings/me',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/me', 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/me");
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{"Bearer {access-token}"},
    }

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

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

GET /settings/me

Get user settings for the current user

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
Response Headers
Status Header Type Format Description
200 ETag string Contains the device object's current ETag.

Update My User Settings

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/useradm/settings/me \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'If-Match: string' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v1/useradm/settings/me HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json
If-Match: string

const inputBody = '{
  "2fa": "enabled"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'If-Match':'string',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/settings/me',
{
  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',
  'If-Match' => 'string',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'If-Match': 'string',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'If-Match' => 'string',
    'Authorization' => 'Bearer {access-token}',
);

$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/me', 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/me");
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"},
        "If-Match": []string{"string"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

POST /settings/me

Set user settings for the current user

Create current user settings or replace existing settings with provided object.

Body parameter

{
  "2fa": "enabled"
}

Parameters

Name In Type Required Description
If-Match header string false Contains the settings' current ETag, and performs the update only if it matches the one stored in the database.
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
412 Precondition Failed ETag doesn't match. None
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

List User Personal Access Tokens

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/useradm/settings/tokens \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/settings/tokens',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/tokens', 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/tokens");
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{"Bearer {access-token}"},
    }

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

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

GET /settings/tokens

Get user Personal Access Tokens

Example responses

200 Response

[
  {
    "id": "806603def19d417d004a4b67e",
    "name": "my_personal_token",
    "last_used": "2022-07-05T11:11:35.725Z",
    "expiration_date": "2023-10-16T07:28:34.725Z",
    "created_ts": "2022-07-05T11:03:27.725Z"
  }
]

Responses

Status Meaning Description Schema
200 OK Endpoint returns a list of tokens. Inline
401 Unauthorized The user cannot be granted authentication. Error
500 Internal Server Error Internal server error. Error
Response Schema

Status Code 200

ListOfTokens

Name Type Required Restrictions Description
ListOfTokens [PersonalAccessToken] false [Personal Access Token Object.]
» id string true Token identifier.
» name string true Name of a token.
» last_used string(date-time) false Date of last usage of a token. The accuracy is 5 minutes.
» expiration_date string(date-time) true Expiration date.
» created_ts string(date-time) true Server-side timestamp of the token creation.

Create Personal Access Token

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/useradm/settings/tokens \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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

const inputBody = '{
  "name": "my_personal_token",
  "expires_in": 28800
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/settings/tokens',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

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

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/tokens', 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/tokens");
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{"Bearer {access-token}"},
    }

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

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

POST /settings/tokens

Create new Personal Access Token

Create new Personal Access Token with given name and expiration.

Body parameter

{
  "name": "my_personal_token",
  "expires_in": 28800
}

Parameters

Name In Type Required Description
body body PersonalAccessTokenRequest true The token object.

Example responses

200 Response

"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NzYxMTkxMzYsImlzcyI6Ik1lbmRlciIsInN1YiI6Ijg1NGIzMTA5LTQ4NjItNGEyNS1hMWZiLWYxMTE2MWNlN2E4NCIsInNjcCI6WyJtZW5kZXIuKiJdfQ.X7Ief4PhPLlR6mA2wh3G3K0Z2tud0rK1QJesxu52NfICSeARmlujczs-_1YZxMwI0s-HgpXHbXIjaSVK80BjxjAM1rqpRGvgqSqG-dU5KmglDpAaTr4VaJci3VFPlVUVTRpI7bfqNMnKZtjmOUAGwjvroDUwX1RwayEmms-efGI"

Responses

Status Meaning Description Schema
200 OK Token has been created. string
400 Bad Request The request body is malformed or expiration time is too big. Error
401 Unauthorized The user cannot be granted authentication. Error
409 Conflict Personal Access Token with the same name already exists. Error
422 Unprocessable Entity Maximum number of Personal Acess Tokens reached for this user. Error
500 Internal Server Error Internal server error. Error

Revoke Personal Access Token

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v1/useradm/settings/tokens/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/settings/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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/settings/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/v1/useradm/settings/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{"Bearer {access-token}"},
    }

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

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

DELETE /settings/tokens/{id}

Revoke Personal Access Token

Parameters

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

Example responses

401 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content Token removed. None
401 Unauthorized The user cannot be granted authentication. Error
500 Internal Server Error Internal server error. Error

Get IDP SAML or OpenID Connect Metadata for the tenant

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata/{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' => 'Bearer {access-token}'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/sso/idp/metadata/{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/sso/idp/metadata/{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{"Bearer {access-token}"},
    }

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

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

GET /sso/idp/metadata/{id}

Get Identity Provider Metadata for the given id

Parameters

Name In Type Required Description
id path string(uuid) true

Example responses

200 Response

"string"

Responses

Status Meaning Description Schema
200 OK Identity Provider Metadata retrieved successfully. string
403 Forbidden Request forbidden, possibly due to feature not being available in current Mender plan. Error
404 Not Found There is nothing to return under the given id Error
500 Internal Server Error Internal server error. Error

Update SAML Metadata

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata/{id} \
  -H 'Content-Type: application/samlmetadata+xml' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

PUT https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata/{id} HTTP/1.1
Host: hosted.mender.io
Content-Type: application/samlmetadata+xml
Accept: application/json

const inputBody = 'string';
const headers = {
  'Content-Type':'application/samlmetadata+xml',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata/{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/samlmetadata+xml',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/samlmetadata+xml',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.put('https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/samlmetadata+xml',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/sso/idp/metadata/{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/sso/idp/metadata/{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/samlmetadata+xml"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

PUT /sso/idp/metadata/{id}

Update SAML Metadata

Body parameter

Parameters

Name In Type Required Description
id path string(uuid) true
body body string true

Example responses

400 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content SAML Metadata updated successfully. None
400 Bad Request The request body is malformed. Error
403 Forbidden Request forbidden, possibly due to feature not being available in current Mender plan. Error
404 Not Found Given id was not associated with any Metadata object. Error
415 Unsupported Media Type Endpoint does not support the Content-Type provided. Error
500 Internal Server Error Internal server error. Error

Delete SAML or OpenID Connect Metadata

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

DELETE https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata/{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' => 'Bearer {access-token}'
}

result = RestClient.delete 'https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.delete('https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/sso/idp/metadata/{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/sso/idp/metadata/{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{"Bearer {access-token}"},
    }

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

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

DELETE /sso/idp/metadata/{id}

Delete SAML or OpenID Connect Metadata

Parameters

Name In Type Required Description
id path string(uuid) true

Example responses

403 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content Request to delete the metadata was accepted None
403 Forbidden Request forbidden, possibly due to feature not being available in current Mender plan. Error
404 Not Found Metadata with the given id was not found. Error
500 Internal Server Error Internal server error. Error

Post SAML, OpenID Connect Metadata, or URL point to them

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata \
  -H 'Content-Type: application/samlmetadata+xml' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata HTTP/1.1
Host: hosted.mender.io
Content-Type: application/samlmetadata+xml
Accept: application/json

const inputBody = 'string';
const headers = {
  'Content-Type':'application/samlmetadata+xml',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata',
{
  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/samlmetadata+xml',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/samlmetadata+xml',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/samlmetadata+xml',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/sso/idp/metadata', 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/sso/idp/metadata");
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/samlmetadata+xml"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

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

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

POST /sso/idp/metadata

Store SAML or OpenID Connect Metadata.

In both cases (SAML and OpenID Connect) we support the passing of the metadata URL which we will automatically query (via GET) and parse the response. Please note that in the case of OpenID Connect you have to pass the url via "well-known" field in json request, and in case of SAML you need to use xml element: "IdentityProviderUrl", for instance: "https://samltest.id/saml/idp".

Body parameter

"string"

Parameters

Name In Type Required Description
body body string true

Example responses

400 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
201 Created SAML or OpenID Connect Metadata stored successfully. None
400 Bad Request The request body is malformed. Error
403 Forbidden Request forbidden, possibly due to feature not being available in current Mender plan. Error
413 Payload Too Large Entity was too large to process. Error
415 Unsupported Media Type Endpoint does not support the Content-Type provided. Error
500 Internal Server Error Internal server error. Error

Get SAML or OpenID Connect Metadata for the tenant

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://hosted.mender.io/api/management/v1/useradm/sso/idp/metadata', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/sso/idp/metadata', 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/sso/idp/metadata");
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{"Bearer {access-token}"},
    }

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

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

GET /sso/idp/metadata

Get an array of SAML or OpenID Connect Metadata for the tenant

Example responses

200 Response

[
  {
    "id": "84430f18-d464-5194-b8ef-b1a15161bb4c",
    "issuer": "https://samltest.id/saml/idp",
    "valid_until": "2038-08-24T21:14:09Z"
  }
]

Responses

Status Meaning Description Schema
200 OK SAML or OpenID Connect Metadata retrieved successfully. Inline
403 Forbidden Request forbidden, possibly due to feature not being available in current Mender plan. Error
500 Internal Server Error Internal server error. Error
Response Schema

Status Code 200

ListOfMetadata

Name Type Required Restrictions Description
ListOfMetadata [SAMLMetadata] false [Metadata structure.]
» id string(uuid) true Metadata Id.
» issuer string true Metadata Issuer.
» valid_until string(date) true Date after which the data is not valid.

Get Service Provider Metadata by id

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/useradm/sso/sp/metadata/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v1/useradm/sso/sp/metadata/{id} HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/sso/sp/metadata/{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' => 'Bearer {access-token}'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/useradm/sso/sp/metadata/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://hosted.mender.io/api/management/v1/useradm/sso/sp/metadata/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/sso/sp/metadata/{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/sso/sp/metadata/{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{"Bearer {access-token}"},
    }

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

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

GET /sso/sp/metadata/{id}

Get Service Provider Metadata for the given id

Parameters

Name In Type Required Description
id path string(uuid) true

Example responses

200 Response

"string"

Responses

Status Meaning Description Schema
200 OK Service Provider Metadata retrieved successfully. string
204 No Content SAML or OpenID Connect Metadata was empty. None
400 Bad Request Request contains a badly formatted id Error
403 Forbidden Request forbidden, possibly due to feature not being available in current Mender plan. Error
404 Not Found There is nothing to return under the given id Error
500 Internal Server Error Internal server error. Error

Get Tenant Limits

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/useradm/limits \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/limits',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/limits', 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/limits");
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{"Bearer {access-token}"},
    }

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

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

GET /limits

Obtain information about limits.

Example responses

200 Response

{
  "limit": 123
}

Responses

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

List Plans

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/useradm/plans \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/plans',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/plans', 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/plans");
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{"Bearer {access-token}"},
    }

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

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

GET /plans

Get list of available plans

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.

Example responses

200 Response

[
  {
    "name": "mender-enterprise",
    "display_name": "Mender Enterprise",
    "features": {
      "rbac": true,
      "audit_logs": false,
      "dynamic_groups": false,
      "terminal": true,
      "file_transfer": true,
      "configuration": true,
      "monitoring": true
    }
  }
]

Responses

Status Meaning Description Schema
200 OK Successful response - list of plans 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
anonymous [Plan] false [Plan descriptor.]
» name string true Unique name of the plan.
» display_name string true Short information about the plan.
» features Features true Features descriptor.
»» rbac boolean false
»» audit_logs boolean false
»» dynamic_groups boolean false
»» terminal boolean false
»» file_transfer boolean false
»» configuration boolean false
»» monitoring boolean false
»» reporting boolean false

Show Plan And Limits

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/useradm/plan_binding \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/plan_binding',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/plan_binding', 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/plan_binding");
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{"Bearer {access-token}"},
    }

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

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

GET /plan_binding

Get plan and limits information for current tenant

Example responses

200 Response

{
  "plan": {
    "product": "Mender",
    "name": "mender-enterprise",
    "display_name": "Mender Enterprise",
    "features": {
      "rbac": true,
      "audit_logs": true
    }
  },
  "limits": {
    "devices": 10,
    "users": 2,
    "audit_logs_days": 2
  }
}

Responses

Status Meaning Description Schema
200 OK Successful response - a plan information is returned. PlanBindingDetails
401 Unauthorized The user cannot be granted authentication. Error
500 Internal Server Error Internal server error. Error

Issue Token

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/useradm/users/tenants/{id}/token \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://hosted.mender.io/api/management/v1/useradm/users/tenants/{id}/token HTTP/1.1
Host: hosted.mender.io
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v1/useradm/users/tenants/{id}/token',
{
  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' => 'Bearer {access-token}'
}

result = RestClient.get 'https://hosted.mender.io/api/management/v1/useradm/users/tenants/{id}/token',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://hosted.mender.io/api/management/v1/useradm/users/tenants/{id}/token', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$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/tenants/{id}/token', 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/tenants/{id}/token");
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{"Bearer {access-token}"},
    }

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

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

GET /users/tenants/{id}/token

Issue a new JWT Token for the given tenant

Issue new JWT Token for given name and expiration.

Parameters

Name In Type Required Description
id path string(uuid) true Tenant identifier.

Example responses

200 Response

"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NzYxMTkxMzYsImlzcyI6Ik1lbmRlciIsInN1YiI6Ijg1NGIzMTA5LTQ4NjItNGEyNS1hMWZiLWYxMTE2MWNlN2E4NCIsInNjcCI6WyJtZW5kZXIuKiJdfQ.X7Ief4PhPLlR6mA2wh3G3K0Z2tud0rK1QJesxu52NfICSeARmlujczs-_1YZxMwI0s-HgpXHbXIjaSVK80BjxjAM1rqpRGvgqSqG-dU5KmglDpAaTr4VaJci3VFPlVUVTRpI7bfqNMnKZtjmOUAGwjvroDUwX1RwayEmms-efGI"

Responses

Status Meaning Description Schema
200 OK Token has been created and returned. string
400 Bad Request Bad request, see error message for details. Error
401 Unauthorized The user cannot be granted authentication. Error
500 Internal Server Error Internal server error. Error

Schemas

LoginOptions

{
  "no_expiry": true,
  "token2fa": "012234"
}

Log in options

Properties
Name Type Required Description
no_expiry boolean false Generate a JWT token with no expiration date.
token2fa string false Two factor authentication token, required if two factor authentication is
enabled and tenant's plan is Professional or Enterprise.

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
sso [SsoObject] false SSO login schemes

SsoObject

{
  "id": "84430f18-d464-5194-b8ef-b1a15161bb4c",
  "kind": "sso/saml"
}

Single Sign On descriptor.

Properties
Name Type Required Description
id string(uuid) true An id of the identity provider.
kind string true Single Sign On provider kind.
subject string false Single Sign On subject.

UserUpdate

{
  "email": "new_email@acme.com",
  "roles": [
    "RBAC_ROLE_DEPLOY_GROUP_TESTING_DEVICES",
    "RBAC_ROLE_READ_ONLY"
  ],
  "password": "new password",
  "current_password": "old password"
}

Update user information.

Properties
Name Type Required Description
email string false A unique email address.
password string false New password.
current_password string false Current password.
roles [string] false List of roles for the user. If not provided existing roles are kept.
» ListOfRoles string false Role name

OwnUserUpdate

{
  "email": "new_email@acme.com",
  "password": "new password",
  "current_password": "old password"
}

Update user information.

Properties
Name Type Required Description
email string false A unique email address.
password string false New password.
current_password string false Current password.

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.
login_ts string(date-time) false Timestamp the of last successful login.
verified boolean false Indicates if the user's email address has been verified.
tfa_status string false User Two Factor Authentication status.
roles [string] false List of user roles.
» ListOfRoles string false Role name
send_reset_password boolean false Flag indicating wether to trigger password reset on user creation.

PersonalAccessTokenRequest

{
  "name": "my_personal_token",
  "expires_in": 28800
}

Personal Access Token Request.

Properties
Name Type Required Description
name string true Name of a token.
expires_in number false Expiration time in seconds (maximum one year - 31536000s).
If you omit it or set it to zero, the Personal Access Token will never expire.

UserWithTenantInfo

{
  "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",
  "tenant_id": "84430f18-d464-5194-b8ef-b1a15161bb4c",
  "tenant_ids": [
    "84430f18-d464-5194-b8ef-b1a15161bb4c",
    "2c481d66-4bd0-43ad-a8b9-61503611c745"
  ]
}

Properties

allOf

Name Type Required Description
anonymous User false User descriptor.

and

Name Type Required Description
anonymous TenantInfo false

and

Name Type Required Description
anonymous TenantsIdName false

TenantInfo

{
  "tenant_id": "string",
  "tenant_ids": [
    "string"
  ]
}

Properties
Name Type Required Description
tenant_id string false Tenant identifier of a tenant, user will log in to by default.
tenant_ids [string] false List of tenant Ids user can login to.

TenantsIdName

[
  {
    "id": "string",
    "name": "string"
  }
]

Properties
Name Type Required Description
anonymous [TenantIdName] false

TenantIdName

{
  "id": "string",
  "name": "string"
}

Properties
Name Type Required Description
id string true Tenant identifier.
name string false Tenant name.

PersonalAccessToken

{
  "id": "806603def19d417d004a4b67e",
  "name": "my_personal_token",
  "last_used": "2022-07-05T11:11:35.725Z",
  "expiration_date": "2023-10-16T07:28:34.725Z",
  "created_ts": "2022-07-05T11:03:27.725Z"
}

Personal Access Token Object.

Properties
Name Type Required Description
id string true Token identifier.
name string true Name of a token.
last_used string(date-time) false Date of last usage of a token. The accuracy is 5 minutes.
expiration_date string(date-time) true Expiration date.
created_ts string(date-time) true Server-side timestamp of the token creation.

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

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

EmailVerificationRequest

{
  "email": "user@mender.io"
}

Email Verification request

Properties
Name Type Required Description
email string true User's email address

EmailVerificationCompletion

{
  "secret": "16fd2706-8baf-433b-82eb-8c7fada847da"
}

Email Verification completion

Properties
Name Type Required Description
secret string true Secret hash received by email by the user

SAMLMetadata

{
  "id": "84430f18-d464-5194-b8ef-b1a15161bb4c",
  "issuer": "https://samltest.id/saml/idp",
  "valid_until": "2038-08-24T21:14:09Z"
}

Metadata structure.

Properties
Name Type Required Description
id string(uuid) true Metadata Id.
issuer string true Metadata Issuer.
valid_until string(date) true Date after which the data is not valid.

Limits

{
  "limit": 123
}

Tenant account limits.

Properties
Name Type Required Description
users Limit true Tenant account limits.

Limit

{
  "count": 10,
  "max": 20
}

Tenant account limits.

Properties
Name Type Required Description
count integer false
max integer true

Plan

{
  "name": "mender-enterprise",
  "display_name": "Mender Enterprise",
  "features": {
    "rbac": true,
    "audit_logs": false,
    "dynamic_groups": false,
    "terminal": true,
    "file_transfer": true,
    "configuration": true,
    "monitoring": true
  }
}

Plan descriptor.

Properties
Name Type Required Description
name string true Unique name of the plan.
display_name string true Short information about the plan.
features Features true Features descriptor.

Features

{
  "rbac": true,
  "audit_logs": false,
  "dynamic_groups": false,
  "terminal": true,
  "file_transfer": true,
  "configuration": true,
  "monitoring": true,
  "reporting": true
}

Features descriptor.

Properties
Name Type Required Description
rbac boolean false
audit_logs boolean false
dynamic_groups boolean false
terminal boolean false
file_transfer boolean false
configuration boolean false
monitoring boolean false
reporting boolean false

PlanLimits

{
  "devices": 10,
  "users": 2,
  "audit_logs_days": 2
}

Plan limits descriptor.

Properties
Name Type Required Description
devices integer false
users integer false
audit_logs_days integer false

PlanBindingDetails

{
  "plan": {
    "product": "Mender",
    "name": "mender-enterprise",
    "display_name": "Mender Enterprise",
    "features": {
      "rbac": true,
      "audit_logs": true
    }
  },
  "limits": {
    "devices": 10,
    "users": 2,
    "audit_logs_days": 2
  }
}

Combination of plan and limits objects.

Properties
Name Type Required Description
plan Plan false Plan descriptor.
limits PlanLimits false Plan limits descriptor.

TenantIdsData

{
  "tenant_ids": [
    "65c76fd6e15517b2f0fbfdf1",
    "65c76fda5e6177ca400a9d4d"
  ]
}

Tenant ids data.

Properties
Name Type Required Description
tenant_ids [string] false
» ListOfIds string false tenant ids

User administration and authentication 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 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:

List Roles

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/useradm/roles \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v2/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/v2/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{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v2/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:

Parameters

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

Example responses

200 Response

[
  {
    "name": "RBAC_ROLE_NAME",
    "description": "Description of the role",
    "permission_sets_with_scope": [
      {
        "name": "ReadReleases"
      },
      {
        "name": "ReadDevices",
        "scope": {
          "type": "DeviceGroups",
          "value": [
            "test",
            "dev"
          ]
        }
      }
    ]
  }
]

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.
» permission_sets_with_scope [PermissionSetWithScope] false [Permission set with optional scope.]
»» name string true Unique permission set name.
»» scope Scope false
»»» type string true Type of the scope.
»»» value [string] true
Enumerated Values
Property Value
type DeviceGroups

Create Role

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/useradm/roles \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://hosted.mender.io/api/management/v2/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",
  "permission_sets_with_scope": [
    {
      "name": "ReadReleases"
    },
    {
      "name": "ReadDevices",
      "scope": {
        "type": "DeviceGroups",
        "value": [
          "test",
          "dev"
        ]
      }
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

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

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v2/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/v2/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{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://hosted.mender.io/api/management/v2/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",
  "permission_sets_with_scope": [
    {
      "name": "ReadReleases"
    },
    {
      "name": "ReadDevices",
      "scope": {
        "type": "DeviceGroups",
        "value": [
          "test",
          "dev"
        ]
      }
    }
  ]
}

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
409 Conflict The role with the same name already exists. Error
500 Internal Server Error Internal server error. Error

Show Role

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/useradm/roles/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v2/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/v2/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{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://hosted.mender.io/api/management/v2/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",
  "permission_sets_with_scope": [
    {
      "name": "ReadReleases"
    },
    {
      "name": "ReadDevices",
      "scope": {
        "type": "DeviceGroups",
        "value": [
          "test",
          "dev"
        ]
      }
    }
  ]
}

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/v2/useradm/roles/{id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

PUT https://hosted.mender.io/api/management/v2/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",
  "permission_sets_with_scope": [
    {
      "name": "ReadReleases"
    },
    {
      "name": "ReadDevices",
      "scope": {
        "type": "DeviceGroups",
        "value": [
          "test",
          "dev"
        ]
      }
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/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' => 'Bearer {access-token}'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v2/useradm/roles/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.put('https://hosted.mender.io/api/management/v2/useradm/roles/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/management/v2/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/v2/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{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "https://hosted.mender.io/api/management/v2/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",
  "permission_sets_with_scope": [
    {
      "name": "ReadReleases"
    },
    {
      "name": "ReadDevices",
      "scope": {
        "type": "DeviceGroups",
        "value": [
          "test",
          "dev"
        ]
      }
    }
  ]
}

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
200 OK 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/v2/useradm/roles/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('DELETE','https://hosted.mender.io/api/management/v2/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/v2/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{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "https://hosted.mender.io/api/management/v2/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 authorization. Error
500 Internal Server Error Internal server error. Error

List Permission Sets

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/useradm/permission_sets \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/useradm/permission_sets',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v2/useradm/permission_sets', 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/useradm/permission_sets");
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{"Bearer {access-token}"},
    }

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

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

GET /permission_sets

List existing permission sets

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 Results page number
per_page query number(integer) false Maximum number of results per page.

Example responses

200 Response

[
  {
    "name": "string",
    "action": "string",
    "object": "string",
    "description": "string",
    "permissions": [
      {
        "action": "http",
        "object": {
          "type": "GET",
          "value": ".*"
        }
      }
    ],
    "supported_scope_types": [
      "string"
    ]
  }
]

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

ListOfPermissionSets

Name Type Required Restrictions Description
ListOfPermissionSets [PermissionSet] false [Permission set descriptor.]
» name string true A unique name.
» action string false
» object string false
» description string false Description of the permission set.
» permissions [Permission] true
»» action string true Action
»» object PermissionObject true
»»» type string true Type
»»» value string true Value
» supported_scope_types [string] false
Enumerated Values
Property Value
action any
action http

Create Permission Set

Code samples

# You can also use wget
curl -X POST https://hosted.mender.io/api/management/v2/useradm/permission_sets \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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

const inputBody = '{
  "name": "string",
  "action": "string",
  "object": "string",
  "description": "string",
  "permissions": [
    {
      "action": "http",
      "object": {
        "type": "GET",
        "value": ".*"
      }
    }
  ],
  "supported_scope_types": [
    "string"
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/useradm/permission_sets',
{
  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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

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

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','https://hosted.mender.io/api/management/v2/useradm/permission_sets', 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/useradm/permission_sets");
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{"Bearer {access-token}"},
    }

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

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

POST /permission_sets

Create permission set.

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

Body parameter

{
  "name": "string",
  "action": "string",
  "object": "string",
  "description": "string",
  "permissions": [
    {
      "action": "http",
      "object": {
        "type": "GET",
        "value": ".*"
      }
    }
  ],
  "supported_scope_types": [
    "string"
  ]
}

Parameters

Name In Type Required Description
body body PermissionSet true New permission set data.

Example responses

401 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
201 Created The permission set was successfully created. None
401 Unauthorized The user cannot be granted authentication. Error
409 Conflict The permission set with the same name already exists.. Error
500 Internal Server Error Internal server error. Error

Get Permission Set

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v2/useradm/permission_sets/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/useradm/permission_sets/{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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','https://hosted.mender.io/api/management/v2/useradm/permission_sets/{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/useradm/permission_sets/{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{"Bearer {access-token}"},
    }

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

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

GET /permission_sets/{id}

Get permission set information

Returns permission set 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 Permission set id.

Example responses

200 Response

{
  "name": "string",
  "action": "string",
  "object": "string",
  "description": "string",
  "permissions": [
    {
      "action": "http",
      "object": {
        "type": "GET",
        "value": ".*"
      }
    }
  ],
  "supported_scope_types": [
    "string"
  ]
}

Responses

Status Meaning Description Schema
200 OK Successful response - a permission set information is returned. PermissionSet
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 Permission Set

Code samples

# You can also use wget
curl -X PUT https://hosted.mender.io/api/management/v2/useradm/permission_sets/{id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

PUT https://hosted.mender.io/api/management/v2/useradm/permission_sets/{id} HTTP/1.1
Host: hosted.mender.io
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "name": "string",
  "action": "string",
  "object": "string",
  "description": "string",
  "permissions": [
    {
      "action": "http",
      "object": {
        "type": "GET",
        "value": ".*"
      }
    }
  ],
  "supported_scope_types": [
    "string"
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/useradm/permission_sets/{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' => 'Bearer {access-token}'
}

result = RestClient.put 'https://hosted.mender.io/api/management/v2/useradm/permission_sets/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.put('https://hosted.mender.io/api/management/v2/useradm/permission_sets/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('PUT','https://hosted.mender.io/api/management/v2/useradm/permission_sets/{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/useradm/permission_sets/{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{"Bearer {access-token}"},
    }

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

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

PUT /permission_sets/{id}

Update permission set.

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

Body parameter

{
  "name": "string",
  "action": "string",
  "object": "string",
  "description": "string",
  "permissions": [
    {
      "action": "http",
      "object": {
        "type": "GET",
        "value": ".*"
      }
    }
  ],
  "supported_scope_types": [
    "string"
  ]
}

Parameters

Name In Type Required Description
id path string true Permission set id.
body body PermissionSet true Updated permission set data.

Example responses

401 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
200 OK Permission Set information updated. None
401 Unauthorized The user cannot be granted authentication. Error
404 Not Found The permission set was not found. Error
500 Internal Server Error Internal server error. Error

Delete Permission Set

Code samples

# You can also use wget
curl -X DELETE https://hosted.mender.io/api/management/v2/useradm/permission_sets/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

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


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://hosted.mender.io/api/management/v2/useradm/permission_sets/{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' => 'Bearer {access-token}'
}

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

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

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

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('DELETE','https://hosted.mender.io/api/management/v2/useradm/permission_sets/{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/useradm/permission_sets/{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{"Bearer {access-token}"},
    }

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

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

DELETE /permission_sets/{id}

Remove permission set 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 Permission set id.

Example responses

401 Response

{
  "error": "missing Authorization header",
  "request_id": "f7881e82-0492-49fb-b459-795654e7188a"
}

Responses

Status Meaning Description Schema
204 No Content Permission set removed. None
401 Unauthorized The user cannot be granted authentication. Error
500 Internal Server Error Internal server error. Error

Schemas

Role

{
  "name": "RBAC_ROLE_NAME",
  "description": "Description of the role",
  "permission_sets_with_scope": [
    {
      "name": "ReadReleases"
    },
    {
      "name": "ReadDevices",
      "scope": {
        "type": "DeviceGroups",
        "value": [
          "test",
          "dev"
        ]
      }
    }
  ]
}

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.
permission_sets_with_scope [PermissionSetWithScope] false [Permission set with optional scope.]

PermissionSetWithScope

{
  "name": "string",
  "scope": {
    "type": "DeviceGroups",
    "value": [
      "test",
      "development"
    ]
  }
}

Permission set with optional scope.

Properties
Name Type Required Description
name string true Unique permission set name.
scope Scope false

Scope

{
  "type": "DeviceGroups",
  "value": [
    "test",
    "development"
  ]
}

Properties
Name Type Required Description
type string true Type of the scope.
value [string] true
Enumerated Values
Property Value
type DeviceGroups

PermissionSet

{
  "name": "string",
  "action": "string",
  "object": "string",
  "description": "string",
  "permissions": [
    {
      "action": "http",
      "object": {
        "type": "GET",
        "value": ".*"
      }
    }
  ],
  "supported_scope_types": [
    "string"
  ]
}

Permission set descriptor.

Properties
Name Type Required Description
name string true A unique name.
action string false
object string false
description string false Description of the permission set.
permissions [Permission] true
supported_scope_types [string] false

Permission

{
  "action": "http",
  "object": {
    "type": "GET",
    "value": ".*"
  }
}

Properties
Name Type Required Description
action string true Action
object PermissionObject true
Enumerated Values
Property Value
action any
action http

PermissionObject

{
  "type": "POST",
  "value": "/api/v1/endpoint"
}

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).

Internal APIs

Audit Logs service

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

Internal API of audit logs service.

Base URLs:

Check Health

Code samples

# You can also use wget
curl -X GET http://mender-auditlogs:8080/api/internal/v1/auditlogs/health \
  -H 'Accept: application/json'

GET http://mender-auditlogs:8080/api/internal/v1/auditlogs/health HTTP/1.1
Host: mender-auditlogs:8080
Accept: application/json


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

fetch('http://mender-auditlogs:8080/api/internal/v1/auditlogs/health',
{
  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 'http://mender-auditlogs:8080/api/internal/v1/auditlogs/health',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-auditlogs:8080/api/internal/v1/auditlogs/health', 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','http://mender-auditlogs:8080/api/internal/v1/auditlogs/health', 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("http://mender-auditlogs:8080/api/internal/v1/auditlogs/health");
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", "http://mender-auditlogs:8080/api/internal/v1/auditlogs/health", data)
    req.Header = headers

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

GET /health

Get status of service

Example responses

500 Response

{
  "error": "error description"
}

Responses

Status Meaning Description Schema
204 No Content Successful response. None
500 Internal Server Error Internal Server Error. Error
503 Service Unavailable Service unavailable Error

Ping

Code samples

# You can also use wget
curl -X GET http://mender-auditlogs:8080/api/internal/v1/auditlogs/alive \
  -H 'Accept: application/json'

GET http://mender-auditlogs:8080/api/internal/v1/auditlogs/alive HTTP/1.1
Host: mender-auditlogs:8080
Accept: application/json


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

fetch('http://mender-auditlogs:8080/api/internal/v1/auditlogs/alive',
{
  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 'http://mender-auditlogs:8080/api/internal/v1/auditlogs/alive',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-auditlogs:8080/api/internal/v1/auditlogs/alive', 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','http://mender-auditlogs:8080/api/internal/v1/auditlogs/alive', 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("http://mender-auditlogs:8080/api/internal/v1/auditlogs/alive");
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", "http://mender-auditlogs:8080/api/internal/v1/auditlogs/alive", data)
    req.Header = headers

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

GET /alive

Get liveliness status of service

Example responses

500 Response

{
  "error": "error description"
}

Responses

Status Meaning Description Schema
204 No Content Successful response. None
500 Internal Server Error Internal Server Error. Error

Delete Audit Logs

Code samples

# You can also use wget
curl -X DELETE http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id} \
  -H 'Accept: application/json'

DELETE http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id} HTTP/1.1
Host: mender-auditlogs:8080
Accept: application/json


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

fetch('http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_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'
}

result = RestClient.delete 'http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.delete('http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}', 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('DELETE','http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_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("http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}", data)
    req.Header = headers

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

DELETE /tenants/{tenant_id}

Delete all the logs for given tenant.

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.

Example responses

500 Response

{
  "error": "error description"
}

Responses

Status Meaning Description Schema
204 No Content All the tenant logs have been successfully deleted. None
500 Internal Server Error Internal Server Error on delete. Error

Get Audit Logs

Code samples

# You can also use wget
curl -X GET http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}/logs \
  -H 'Accept: application/json'

GET http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}/logs HTTP/1.1
Host: mender-auditlogs:8080
Accept: application/json


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

fetch('http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}/logs',
{
  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 'http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}/logs',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}/logs', 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','http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}/logs', 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("http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}/logs");
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", "http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}/logs", data)
    req.Header = headers

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

GET /tenants/{tenant_id}/logs

Returns a list of audit log objects.

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.
page query number(integer) false Starting page.
per_page query number(integer) false Number of results per page.
created_before query number(integer) false List only log entries created before and equal to Unix timestamp (UTC)
created_after query number(integer) false List only log entries created after and equal to Unix timestamp (UTC)
actor_id query string false If present, limits the results only to logs where actor has given id.
actor_type query string false If present, limits the results only to logs where actor is of a given type.
actor_email query string false If present, limits the results only to logs where actors has given email address.
object_id query string false If present, limits the results only to logs where object has given id.
object_type query string false If present, limits the results only to logs where object is of a given type.
object_deployment_name query string false If present, limits the results only to logs where object is a deployment with a given name.
sort query string false Supports sorting the log list by creation date.
Detailed descriptions

sort: Supports sorting the log list by creation date. By default logs are sorted by creation date in descending order (newest first).

Enumerated Values
Parameter Value
actor_type user
actor_type device
object_type user
object_type deployment
object_type artifact
object_type device
sort asc
sort desc

Example responses

200 Response

[
  {
    "actor": {
      "id": "string",
      "type": "user",
      "email": "string",
      "identity_data": "string"
    },
    "time": "2019-08-24T14:15:22Z",
    "action": "create",
    "object": {
      "id": "string",
      "type": "user",
      "user": {
        "email": "user@acme.com"
      },
      "deployment": {
        "application/json": {
          "name": "production",
          "artifact_name": "Application 0.0.1"
        }
      },
      "artifact": {
        "application/json": {
          "name": "artifact_name_1"
        }
      },
      "device": {
        "id": "e1ba5bee-c45d-11eb-887d-3fd47bdc3990",
        "identity_data": "{\"mac_address\": \"2C:54:91:88:C9:E3\", \"sn\": \"1229224105105176\"}"
      }
    },
    "change": "string"
  }
]

Responses

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

Status Code 200

ListOfLogs

Name Type Required Restrictions Description
ListOfLogs [AuditLog] false A list of audit logs is returned.
» actor Actor true The actor may be a user or device.
Depending on the type of the actor different information will be available.
»» id string true A unique identifier of the actor.
»» type string true The type of the actor.
»» email string false The email address of the user.
»» identity_data string false The identity data of the device.
» time string(date-time) true
» action string true
» object Object true Various types of objects are supported.
Depending on the type of object different information will be available.
»» id string true A unique identifier of the object.
»» type string true The type of the object.
»» user User false The user descriptor.
»»» email string true The email address of the user.
»» deployment Deployment false The deployment descriptor.
»»» name string true
»»» artifact_name string true
»» artifact Artifact false The artifact descriptor.
»»» name string true
»» device Device false Device descriptor.
»»» id string false Device ID.
»»» identity_data string true Vendor-specific JSON representation of the device identity data (MACs, serial numbers, etc.).
» change string false
Enumerated Values
Property Value
type user
type device
action create
action update
action delete
action abort
action open_terminal
action close_terminal
action open_portforward
action close_portforward
action download_file
action upload_file
action set_configuration
action deploy_configuration
action upload
type user
type deployment
type artifact
type device
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.

Save Audit Log

Code samples

# You can also use wget
curl -X POST http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}/logs \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}/logs HTTP/1.1
Host: mender-auditlogs:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "actor": {
    "id": "string",
    "type": "user",
    "email": "string",
    "identity_data": "string"
  },
  "time": "2019-08-24T14:15:22Z",
  "action": "create",
  "object": {
    "id": "string",
    "type": "user",
    "user": {
      "email": "user@acme.com"
    },
    "deployment": {
      "application/json": {
        "name": "production",
        "artifact_name": "Application 0.0.1"
      }
    },
    "artifact": {
      "application/json": {
        "name": "artifact_name_1"
      }
    },
    "device": {
      "id": "e1ba5bee-c45d-11eb-887d-3fd47bdc3990",
      "identity_data": "{\"mac_address\": \"2C:54:91:88:C9:E3\", \"sn\": \"1229224105105176\"}"
    }
  },
  "change": "string"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}/logs',
{
  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 'http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}/logs',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}/logs', 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','http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}/logs', 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("http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}/logs");
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", "http://mender-auditlogs:8080/api/internal/v1/auditlogs/tenants/{tenant_id}/logs", data)
    req.Header = headers

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

POST /tenants/{tenant_id}/logs

Log event.

Body parameter

{
  "actor": {
    "id": "string",
    "type": "user",
    "email": "string",
    "identity_data": "string"
  },
  "time": "2019-08-24T14:15:22Z",
  "action": "create",
  "object": {
    "id": "string",
    "type": "user",
    "user": {
      "email": "user@acme.com"
    },
    "deployment": {
      "application/json": {
        "name": "production",
        "artifact_name": "Application 0.0.1"
      }
    },
    "artifact": {
      "application/json": {
        "name": "artifact_name_1"
      }
    },
    "device": {
      "id": "e1ba5bee-c45d-11eb-887d-3fd47bdc3990",
      "identity_data": "{\"mac_address\": \"2C:54:91:88:C9:E3\", \"sn\": \"1229224105105176\"}"
    }
  },
  "change": "string"
}

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.
body body AuditLog true

Example responses

500 Response

{
  "error": "error description"
}

Responses

Status Meaning Description Schema
201 Created Event has been successfully logged. None
500 Internal Server Error Internal Server Error. Error

Schemas

AuditLog

{
  "actor": {
    "id": "string",
    "type": "user",
    "email": "string",
    "identity_data": "string"
  },
  "time": "2019-08-24T14:15:22Z",
  "action": "create",
  "object": {
    "id": "string",
    "type": "user",
    "user": {
      "email": "user@acme.com"
    },
    "deployment": {
      "application/json": {
        "name": "production",
        "artifact_name": "Application 0.0.1"
      }
    },
    "artifact": {
      "application/json": {
        "name": "artifact_name_1"
      }
    },
    "device": {
      "id": "e1ba5bee-c45d-11eb-887d-3fd47bdc3990",
      "identity_data": "{\"mac_address\": \"2C:54:91:88:C9:E3\", \"sn\": \"1229224105105176\"}"
    }
  },
  "change": "string"
}

Audit log.

Properties
Name Type Required Description
actor Actor true The actor may be a user or device.
Depending on the type of the actor different information will be available.
time string(date-time) true
action string true
object Object true Various types of objects are supported.
Depending on the type of object different information will be available.
change string false
Enumerated Values
Property Value
action create
action update
action delete
action abort
action open_terminal
action close_terminal
action open_portforward
action close_portforward
action download_file
action upload_file
action set_configuration
action deploy_configuration
action upload

Actor

{
  "id": "string",
  "type": "user",
  "email": "string",
  "identity_data": "string"
}

The actor may be a user or device. Depending on the type of the actor different information will be available.

Properties
Name Type Required Description
id string true A unique identifier of the actor.
type string true The type of the actor.
email string false The email address of the user.
identity_data string false The identity data of the device.
Enumerated Values
Property Value
type user
type device

Object

{
  "id": "string",
  "type": "user",
  "user": {
    "email": "user@acme.com"
  },
  "deployment": {
    "application/json": {
      "name": "production",
      "artifact_name": "Application 0.0.1"
    }
  },
  "artifact": {
    "application/json": {
      "name": "artifact_name_1"
    }
  },
  "device": {
    "id": "e1ba5bee-c45d-11eb-887d-3fd47bdc3990",
    "identity_data": "{\"mac_address\": \"2C:54:91:88:C9:E3\", \"sn\": \"1229224105105176\"}"
  }
}

Various types of objects are supported. Depending on the type of object different information will be available.

Properties
Name Type Required Description
id string true A unique identifier of the object.
type string true The type of the object.
user User false The user descriptor.
deployment Deployment false The deployment descriptor.
artifact Artifact false The artifact descriptor.
device Device false Device descriptor.
Enumerated Values
Property Value
type user
type deployment
type artifact
type device

User

{
  "email": "user@acme.com"
}

The user descriptor.

Properties
Name Type Required Description
email string true The email address of the user.

Deployment

{
  "application/json": {
    "name": "production",
    "artifact_name": "Application 0.0.1"
  }
}

The deployment descriptor.

Properties
Name Type Required Description
name string true
artifact_name string true

Artifact

{
  "application/json": {
    "name": "artifact_name_1"
  }
}

The artifact descriptor.

Properties
Name Type Required Description
name string true

Device

{
  "id": "e1ba5bee-c45d-11eb-887d-3fd47bdc3990",
  "identity_data": "{\"mac_address\": \"2C:54:91:88:C9:E3\", \"sn\": \"1229224105105176\"}"
}

Device descriptor.

Properties
Name Type Required Description
id string false Device ID.
identity_data string true Vendor-specific JSON representation of the device identity data (MACs, serial numbers, etc.).

Error

{
  "error": "error description"
}

The error descriptor.

Properties
Name Type Required Description
error string false The description of the error.

Deployments Internal API

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

Internal API of deployments service

Base URLs:

Get Storage Usage

Code samples

# You can also use wget
curl -X GET http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/limits/storage \
  -H 'Accept: application/json'

GET http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/limits/storage HTTP/1.1
Host: mender-deployments:8080
Accept: application/json


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

fetch('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/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'
}

result = RestClient.get 'http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/limits/storage',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/limits/storage', 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','http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/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("http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/limits/storage", data)
    req.Header = headers

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

GET /tenants/{id}/limits/storage

Get storage limit and current storage usage for given tenant

Get storage limit and current storage usage for given tenant. If the limit value is 0 it means storage space is unlimited

Parameters

Name In Type Required Description
id path string true Tenant ID

Example responses

200 Response

{
  "limit": 1073741824,
  "usage": 536870912
}

Responses

Status Meaning Description Schema
200 OK Successful response. StorageUsage
500 Internal Server Error Internal Server Error. Error

Set Storage Limit

Code samples

# You can also use wget
curl -X PUT http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/limits/storage \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

PUT http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/limits/storage HTTP/1.1
Host: mender-deployments:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "limit": 1073741824
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/limits/storage',
{
  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 'http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/limits/storage',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.put('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/limits/storage', 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','http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/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("http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/limits/storage");
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", "http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/limits/storage", data)
    req.Header = headers

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

PUT /tenants/{id}/limits/storage

Set storage limit for given tenant

Set storage limit for given tenant. If the limit value is 0 it means storage space is unlimited

Body parameter

{
  "limit": 1073741824
}

Parameters

Name In Type Required Description
id path string true Tenant ID
body body StorageLimit true

Example responses

400 Response

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

Responses

Status Meaning Description Schema
204 No Content Limit information updated. None
400 Bad Request The request body is malformed. Error
500 Internal Server Error Internal server error. Error

Create Tenant

Code samples

# You can also use wget
curl -X POST http://mender-deployments:8080/api/internal/v1/deployments/tenants \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-deployments:8080/api/internal/v1/deployments/tenants HTTP/1.1
Host: mender-deployments:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "tenant_id": "58be8208dd77460001fe0d78"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-deployments:8080/api/internal/v1/deployments/tenants',
{
  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 'http://mender-deployments:8080/api/internal/v1/deployments/tenants',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('http://mender-deployments:8080/api/internal/v1/deployments/tenants', 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','http://mender-deployments:8080/api/internal/v1/deployments/tenants', 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("http://mender-deployments:8080/api/internal/v1/deployments/tenants");
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", "http://mender-deployments:8080/api/internal/v1/deployments/tenants", data)
    req.Header = headers

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

POST /tenants

Provision a new tenant

Sets up all tenant-related infrastructure, e.g. a migrated tenant's database.

Body parameter

{
  "tenant_id": "58be8208dd77460001fe0d78"
}

Parameters

Name In Type Required Description
body body NewTenant true New tenant descriptor.

Example responses

500 Response

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

Responses

Status Meaning Description Schema
201 Created Tenant was successfully provisioned. None
400 Bad Request Bad request. None
500 Internal Server Error Internal server error. Error

Get Deployments

Code samples

# You can also use wget
curl -X GET http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/deployments \
  -H 'Accept: application/json'

GET http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/deployments HTTP/1.1
Host: mender-deployments:8080
Accept: application/json


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

fetch('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/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'
}

result = RestClient.get 'http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/deployments',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/deployments', 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','http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/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("http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/deployments", data)
    req.Header = headers

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

GET /tenants/{id}/deployments

Get all deployments for specific tenant

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
id path string true Tenant ID
status query string false Deployment status filter.
search query string false Deployment name or description filter.
page query number(integer) false Results page number
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

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
  }
]

400 Response

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

Responses

Status Meaning Description Schema
200 OK Successful response. Inline
400 Bad Request Invalid Request. 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 false
» artifacts [string] false An array of artifact's identifiers.
» type string false
Enumerated Values
Property Value
status inprogress
status pending
status finished
type configuration
type software
Response Headers
Status Header Type Format Description
200 X-Total-Count integer Total number of deployments matching query.

Upload artifact

Code samples

# You can also use wget
curl -X POST http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/artifacts \
  -H 'Content-Type: multipart/form-data' \
  -H 'Accept: application/json'

POST http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/artifacts HTTP/1.1
Host: mender-deployments:8080
Content-Type: multipart/form-data
Accept: application/json

const inputBody = '{
  "artifact_id": "string",
  "size": 0,
  "description": "string",
  "artifact": "string"
}';
const headers = {
  'Content-Type':'multipart/form-data',
  'Accept':'application/json'
};

fetch('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/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'
}

result = RestClient.post 'http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/artifacts',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'multipart/form-data',
  'Accept': 'application/json'
}

r = requests.post('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/artifacts', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'multipart/form-data',
    'Accept' => 'application/json',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/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("http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/artifacts", data)
    req.Header = headers

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

POST /tenants/{id}/artifacts

Upload mender artifact

Upload mender artifact to a specific tenant. Multipart request with meta and artifact. Supports artifact versions v1, v2, v3.

Body parameter

artifact_id: string
size: 0
description: string
artifact: string

Parameters

Name In Type Required Description
id path string true Tenant ID, or "default" if running in non-multitenant setup
body body object false
» artifact_id body string false Artifact ID, optional; the server generates a randome one if not provided.
» 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.

Example responses

400 Response

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

Responses

Status Meaning Description Schema
201 Created Artifact uploaded. None
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error
Response Headers
Status Header Type Format Description
201 Location string URL of the newly uploaded artifact.

Check Health

Code samples

# You can also use wget
curl -X GET http://mender-deployments:8080/api/internal/v1/deployments/health \
  -H 'Accept: application/json'

GET http://mender-deployments:8080/api/internal/v1/deployments/health HTTP/1.1
Host: mender-deployments:8080
Accept: application/json


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

fetch('http://mender-deployments:8080/api/internal/v1/deployments/health',
{
  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 'http://mender-deployments:8080/api/internal/v1/deployments/health',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-deployments:8080/api/internal/v1/deployments/health', 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','http://mender-deployments:8080/api/internal/v1/deployments/health', 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("http://mender-deployments:8080/api/internal/v1/deployments/health");
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", "http://mender-deployments:8080/api/internal/v1/deployments/health", data)
    req.Header = headers

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

GET /health

Check the health of the service

Example responses

Unexpected internal error

{
  "error": "internal error",
  "request_id": "ffd712be-d697-4cb7-814b-88ff1e2eb5f6"
}

Service unhealthy / not ready to accept traffic. At least one dependency is not running.

{
  "error": "error reaching MongoDB: context deadline exceeded",
  "request_id": "ffd712be-d697-4cb7-814b-88ff1e2eb5f6"
}

Responses

Status Meaning Description Schema
204 No Content Service is healthy and all dependencies are up and running. None
500 Internal Server Error Unexpected internal error Error
503 Service Unavailable Service unhealthy / not ready to accept traffic. At least one dependency is not running. Error

Check Liveliness

Code samples

# You can also use wget
curl -X GET http://mender-deployments:8080/api/internal/v1/deployments/alive \
  -H 'Accept: application/json'

GET http://mender-deployments:8080/api/internal/v1/deployments/alive HTTP/1.1
Host: mender-deployments:8080
Accept: application/json


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

fetch('http://mender-deployments:8080/api/internal/v1/deployments/alive',
{
  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 'http://mender-deployments:8080/api/internal/v1/deployments/alive',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-deployments:8080/api/internal/v1/deployments/alive', 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','http://mender-deployments:8080/api/internal/v1/deployments/alive', 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("http://mender-deployments:8080/api/internal/v1/deployments/alive");
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", "http://mender-deployments:8080/api/internal/v1/deployments/alive", data)
    req.Header = headers

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

GET /alive

*Trivial endpoint that unconditionally returns an empty 200 response whenever the API handler is running correctly. *

Example responses

500 Response

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

Responses

Status Meaning Description Schema
204 No Content Service is up and running. None
500 Internal Server Error Internal API error Error

Get Storage Settings

Code samples

# You can also use wget
curl -X GET http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/storage/settings \
  -H 'Accept: application/json'

GET http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/storage/settings HTTP/1.1
Host: mender-deployments:8080
Accept: application/json


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

fetch('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/storage/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'
}

result = RestClient.get 'http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/storage/settings',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/storage/settings', 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','http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/storage/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("http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/storage/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/storage/settings", data)
    req.Header = headers

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

GET /tenants/{id}/storage/settings

Get storage setting for a given tenant

Returns an object with per tenant storage layer specific settings.

Parameters

Name In Type Required Description
id path string true Tenant ID

Example responses

200 Response

{
  "region": "us-east-1",
  "bucket": "mender-artifacts-unique-bucket-name",
  "uri": "example.internal:9000",
  "external_uri": "example.com",
  "key": "<key>",
  "secret": "<secret>",
  "token": "<token>",
  "force_path_style": false,
  "use_accelerate": false
}

Responses

Status Meaning Description Schema
200 OK Successful response with all available settings. StorageSettings
500 Internal Server Error Internal error. Error

Set Storage Settings

Code samples

# You can also use wget
curl -X PUT http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/storage/settings \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

PUT http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/storage/settings HTTP/1.1
Host: mender-deployments:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "region": "us-east-1",
  "bucket": "mender-artifacts-unique-bucket-name",
  "uri": "example.internal:9000",
  "external_uri": "example.com",
  "key": "<key>",
  "secret": "<secret>",
  "token": "<token>",
  "force_path_style": false,
  "use_accelerate": false
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/storage/settings',
{
  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 'http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/storage/settings',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.put('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/storage/settings', 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','http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/storage/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("http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/storage/settings");
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", "http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}/storage/settings", data)
    req.Header = headers

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

PUT /tenants/{id}/storage/settings

Set storage settings for a given tenant

Set the storage layer settings for a given tenant.

Body parameter

{
  "region": "us-east-1",
  "bucket": "mender-artifacts-unique-bucket-name",
  "uri": "example.internal:9000",
  "external_uri": "example.com",
  "key": "<key>",
  "secret": "<secret>",
  "token": "<token>",
  "force_path_style": false,
  "use_accelerate": false
}

Parameters

Name In Type Required Description
id path string true Tenant ID
body body StorageSettings false Settings to set.
Detailed descriptions

body: Settings to set. If set to null or an empty object, the tenant will use the default settings.

Example responses

400 Response

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

Responses

Status Meaning Description Schema
204 No Content Settings updated. None
400 Bad Request The request body is malformed. Error
500 Internal Server Error Internal server error. Error

Delete tenant

Code samples

# You can also use wget
curl -X DELETE http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id} \
  -H 'Accept: application/json'

DELETE http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id} HTTP/1.1
Host: mender-deployments:8080
Accept: application/json


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

fetch('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{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'
}

result = RestClient.delete 'http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.delete('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}', 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('DELETE','http://mender-deployments:8080/api/internal/v1/deployments/tenants/{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("http://mender-deployments:8080/api/internal/v1/deployments/tenants/{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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-deployments:8080/api/internal/v1/deployments/tenants/{id}", data)
    req.Header = headers

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

DELETE /tenants/{id}

Delete all the tenant data

Deletes all the tenant data.

Parameters

Name In Type Required Description
id path string true Tenant ID

Example responses

500 Response

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

Responses

Status Meaning Description Schema
204 No Content Successful removal. None
500 Internal Server Error Internal server error on removal. Error

List Device Deployments entries

Code samples

# You can also use wget
curl -X GET http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/devices \
  -H 'Accept: application/json'

GET http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/devices HTTP/1.1
Host: mender-deployments:8080
Accept: application/json


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

fetch('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/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'
}

result = RestClient.get 'http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/devices',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/devices', 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','http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/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("http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/devices", data)
    req.Header = headers

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

GET /tenants/{tenant_id}/deployments/devices

Return the Deployments history entries for the specified IDs

Return the Deployments history entries for the specified IDs

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID
id query array[string] false Deployment Device ID filter. Can be repeated to query a set of entries.

Example responses

200 Response

[
  {
    "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
    "deployment": {
      "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
      "name": "production",
      "artifact_name": "Application 0.0.1",
      "status": "inprogress",
      "created": "2016-02-11T13:03:17.063493443Z",
      "device_count": 100
    },
    "device": {
      "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
      "device_type": "Raspberry Pi 3",
      "status": "installing",
      "finished": "2016-03-11T13:03:17.063493443Z",
      "created": "2016-02-11T13:03:17.063493443Z",
      "state": "installing",
      "substate": "installing.enter;script:foo-bar",
      "log": false,
      "image": {
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "name": "Application 1.0.0",
        "meta": {
          "description": "Johns Monday test build"
        },
        "meta_artifact": {
          "name": "Application 1.0.0",
          "device_types_compatible": [
            "Beagle Bone"
          ],
          "info": {
            "format": "mender",
            "version": 3
          },
          "signed": false,
          "updates": [
            {
              "type_info": {
                "type": "rootfs-image"
              },
              "files": [
                {
                  "name": "rootfs-image-1",
                  "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                  "size": 123,
                  "date": "2016-03-11T13:03:17.063+0000"
                }
              ],
              "meta_data": {}
            }
          ],
          "artifact_provides": {
            "artifact_name": "test",
            "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
            "rootfs-image.version": "test"
          },
          "artifact_depends": {
            "device_type": [
              "test"
            ]
          },
          "clears_artifact_provides": [
            "rootfs-image.*"
          ]
        },
        "size": 36891648,
        "modified": "2016-03-11T13:03:17.063493443Z"
      }
    }
  }
]

Responses

Status Meaning Description Schema
200 OK OK Inline
400 Bad Request Bad request. None
500 Internal Server Error Internal server error. Error
Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [DeviceDeployment] false
» id string false
» deployment Deployment true
»» 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 false
»» artifacts [string] false An array of artifact's identifiers.
»» type string false
» device DeviceWithImage true
»» id string true Device identifier.
»» status DeviceStatus true
»» created string(date-time) false
»» finished string(date-time) false
»» deleted 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
»» image object false
»»» id string false Image ID
»»» meta object false
»»»» description string false Image description
»»» meta_artifact object false
»»»» name string false
»»»» device_types_compatible [string] false An array of compatible device types.
»»»» info ArtifactInfo false Information about artifact format and version.
»»»»» format string false
»»»»» version integer false
»»»» signed boolean false Idicates if artifact is signed or not.
»»»» updates [Update] false [Single updated to be applied.
]
»»»»» type_info ArtifactTypeInfo false Information about update type.
»»»»»» type string false Note that for emtpy Artifacts, the type is 'null'
»»»»» 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)
»»»» artifact_provides object false List of Artifact provides.

Map of key/value pairs, where both keys and values are strings.
»»»»» additionalProperties string false
»»»» artifact_depends object false List of Artifact depends.

Map of key/value pairs, where keys are strings and values are lists of strings.
»»»»» additionalProperties [string] false
»»»» clears_artifact_provides [string] false List of Clear Artifact provides.
»»» size integer false Image size in bytes
»»» modified string(date-time) false Creation / last edition of any of the artifact properties
Enumerated Values
Property Value
status inprogress
status pending
status finished
type configuration
type software
status failure
status aborted
status pause_before_installing
status pause_before_committing
status pause_before_rebooting
status downloading
status installing
status rebooting
status pending
status success
status noartifact
status already-installed
status decommissioned

List Deployments for a Device

Code samples

# You can also use wget
curl -X GET http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/devices/{id} \
  -H 'Accept: application/json'

GET http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/devices/{id} HTTP/1.1
Host: mender-deployments:8080
Accept: application/json


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

fetch('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/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'
}

result = RestClient.get 'http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/devices/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/devices/{id}', 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','http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/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("http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/devices/{id}", data)
    req.Header = headers

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

GET /tenants/{tenant_id}/deployments/devices/{id}

Return the Deployments history for a Device

Return the Deployments history for the specified Device, listing all its Deployments.

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID
id path string true System wide device identifier
status query string false Filter deployments by status for the given device.
page query number(integer) false Starting page.
per_page query number(integer) false Maximum number of results per page.
Enumerated Values
Parameter Value
status failure
status aborted
status pause_before_installing
status pause_before_committing
status pause_before_rebooting
status downloading
status installing
status rebooting
status pending
status success
status noartifact
status already-installed
status decommissioned
status pause
status active
status finished

Example responses

200 Response

[
  {
    "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
    "deployment": {
      "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
      "name": "production",
      "artifact_name": "Application 0.0.1",
      "status": "inprogress",
      "created": "2016-02-11T13:03:17.063493443Z",
      "device_count": 100
    },
    "device": {
      "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
      "device_type": "Raspberry Pi 3",
      "status": "installing",
      "finished": "2016-03-11T13:03:17.063493443Z",
      "created": "2016-02-11T13:03:17.063493443Z",
      "state": "installing",
      "substate": "installing.enter;script:foo-bar",
      "log": false,
      "image": {
        "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
        "name": "Application 1.0.0",
        "meta": {
          "description": "Johns Monday test build"
        },
        "meta_artifact": {
          "name": "Application 1.0.0",
          "device_types_compatible": [
            "Beagle Bone"
          ],
          "info": {
            "format": "mender",
            "version": 3
          },
          "signed": false,
          "updates": [
            {
              "type_info": {
                "type": "rootfs-image"
              },
              "files": [
                {
                  "name": "rootfs-image-1",
                  "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                  "size": 123,
                  "date": "2016-03-11T13:03:17.063+0000"
                }
              ],
              "meta_data": {}
            }
          ],
          "artifact_provides": {
            "artifact_name": "test",
            "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
            "rootfs-image.version": "test"
          },
          "artifact_depends": {
            "device_type": [
              "test"
            ]
          },
          "clears_artifact_provides": [
            "rootfs-image.*"
          ]
        },
        "size": 36891648,
        "modified": "2016-03-11T13:03:17.063493443Z"
      }
    }
  }
]

Responses

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

Status Code 200

Name Type Required Restrictions Description
anonymous [DeviceDeployment] false
» id string false
» deployment Deployment true
»» 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 false
»» artifacts [string] false An array of artifact's identifiers.
»» type string false
» device DeviceWithImage true
»» id string true Device identifier.
»» status DeviceStatus true
»» created string(date-time) false
»» finished string(date-time) false
»» deleted 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
»» image object false
»»» id string false Image ID
»»» meta object false
»»»» description string false Image description
»»» meta_artifact object false
»»»» name string false
»»»» device_types_compatible [string] false An array of compatible device types.
»»»» info ArtifactInfo false Information about artifact format and version.
»»»»» format string false
»»»»» version integer false
»»»» signed boolean false Idicates if artifact is signed or not.
»»»» updates [Update] false [Single updated to be applied.
]
»»»»» type_info ArtifactTypeInfo false Information about update type.
»»»»»» type string false Note that for emtpy Artifacts, the type is 'null'
»»»»» 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)
»»»» artifact_provides object false List of Artifact provides.

Map of key/value pairs, where both keys and values are strings.
»»»»» additionalProperties string false
»»»» artifact_depends object false List of Artifact depends.

Map of key/value pairs, where keys are strings and values are lists of strings.
»»»»» additionalProperties [string] false
»»»» clears_artifact_provides [string] false List of Clear Artifact provides.
»»» size integer false Image size in bytes
»»» modified string(date-time) false Creation / last edition of any of the artifact properties
Enumerated Values
Property Value
status inprogress
status pending
status finished
type configuration
type software
status failure
status aborted
status pause_before_installing
status pause_before_committing
status pause_before_rebooting
status downloading
status installing
status rebooting
status pending
status success
status noartifact
status already-installed
status decommissioned

Remove Device from Deployments

Code samples

# You can also use wget
curl -X DELETE http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/devices/{id} \
  -H 'Accept: application/json'

DELETE http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/devices/{id} HTTP/1.1
Host: mender-deployments:8080
Accept: application/json


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

fetch('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/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'
}

result = RestClient.delete 'http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/devices/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.delete('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/devices/{id}', 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('DELETE','http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/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("http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/deployments/devices/{id}", data)
    req.Header = headers

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

DELETE /tenants/{tenant_id}/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
tenant_id path string true Tenant ID
id path string true System wide device identifier

Example responses

500 Response

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

Responses

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

Create Deployment

Code samples

# You can also use wget
curl -X POST http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/configuration/deployments/{deployment_id}/devices/{device_id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/configuration/deployments/{deployment_id}/devices/{device_id} HTTP/1.1
Host: mender-deployments:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "name": "config-1.1",
  "configuration": "{\"foo\":\"bar\"}"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/configuration/deployments/{deployment_id}/devices/{device_id}',
{
  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 'http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/configuration/deployments/{deployment_id}/devices/{device_id}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/configuration/deployments/{deployment_id}/devices/{device_id}', 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','http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/configuration/deployments/{deployment_id}/devices/{device_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("http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/configuration/deployments/{deployment_id}/devices/{device_id}");
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", "http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/configuration/deployments/{deployment_id}/devices/{device_id}", data)
    req.Header = headers

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

POST /tenants/{tenant_id}/configuration/deployments/{deployment_id}/devices/{device_id}

Create a configuration deployment

Deploy configuration to a specified device. The artifact will be auto-generated based on the configuration object provided with the deployment constructor.

Body parameter

{
  "name": "config-1.1",
  "configuration": "{\"foo\":\"bar\"}"
}

Parameters

Name In Type Required Description
tenant_id path string true Tenant identifier.
device_id path string true Device identifier.
deployment_id path string true Deployment identifier.
body body NewConfigurationDeployment true New deployment that needs to be created.

Example responses

400 Response

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

Responses

Status Meaning Description Schema
201 Created New configuration deployment created. None
400 Bad Request Invalid Request. Error
409 Conflict The deployment with a given id already exists. 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.

Get Tenant Configuration

Code samples

# You can also use wget
curl -X GET http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/config \
  -H 'Accept: application/json'

GET http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/config HTTP/1.1
Host: mender-deployments:8080
Accept: application/json


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

fetch('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/config',
{
  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 'http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/config',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/config', 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','http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/config', 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("http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/config");
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", "http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/config", data)
    req.Header = headers

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

GET /tenants/{tenant_id}/config

Get Tenant specific configuration

Parameters

Name In Type Required Description
tenant_id path string true Tenant identifier.

Example responses

200 Response

{
  "delta": {
    "enabled": true,
    "binary_delta": {
      "xdelta_args": {
        "disable_checksum": false,
        "disable_external_decompression": false,
        "compression_level": 6,
        "source_window_size": 0,
        "input_window_size": 0,
        "compression_duplicates_window": 0,
        "instruction_buffer_size": 0
      },
      "timeout": 0
    },
    "binary_delta_limits": {
      "xdelta_args_limits": {
        "compression_level": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "source_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "input_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "compression_duplicates_window": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "instruction_buffer_size": {
          "min": 5,
          "max": 100,
          "default": 10
        }
      },
      "timeout": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "jobs_in_parallel": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "queue_length": {
        "min": 5,
        "max": 100,
        "default": 10
      }
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successful response. Configuration
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error
Response Headers
Status Header Type Format Description
200 ETag string Contains the configuration object's current ETag.

Update Tenant Configuration

Code samples

# You can also use wget
curl -X PUT http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/config \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'If-Match: string'

PUT http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/config HTTP/1.1
Host: mender-deployments:8080
Content-Type: application/json
Accept: application/json
If-Match: string

const inputBody = '{
  "delta": {
    "enabled": true,
    "binary_delta": {
      "xdelta_args": {
        "disable_checksum": false,
        "disable_external_decompression": false,
        "compression_level": 6,
        "source_window_size": 0,
        "input_window_size": 0,
        "compression_duplicates_window": 0,
        "instruction_buffer_size": 0
      },
      "timeout": 0
    },
    "binary_delta_limits": {
      "xdelta_args_limits": {
        "compression_level": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "source_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "input_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "compression_duplicates_window": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "instruction_buffer_size": {
          "min": 5,
          "max": 100,
          "default": 10
        }
      },
      "timeout": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "jobs_in_parallel": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "queue_length": {
        "min": 5,
        "max": 100,
        "default": 10
      }
    }
  }
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'If-Match':'string'
};

fetch('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/config',
{
  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',
  'If-Match' => 'string'
}

result = RestClient.put 'http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/config',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'If-Match': 'string'
}

r = requests.put('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/config', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'If-Match' => 'string',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('PUT','http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/config', 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("http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/config");
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"},
        "If-Match": []string{"string"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/config", data)
    req.Header = headers

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

PUT /tenants/{tenant_id}/config

Set tenant configuration

Body parameter

{
  "delta": {
    "enabled": true,
    "binary_delta": {
      "xdelta_args": {
        "disable_checksum": false,
        "disable_external_decompression": false,
        "compression_level": 6,
        "source_window_size": 0,
        "input_window_size": 0,
        "compression_duplicates_window": 0,
        "instruction_buffer_size": 0
      },
      "timeout": 0
    },
    "binary_delta_limits": {
      "xdelta_args_limits": {
        "compression_level": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "source_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "input_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "compression_duplicates_window": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "instruction_buffer_size": {
          "min": 5,
          "max": 100,
          "default": 10
        }
      },
      "timeout": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "jobs_in_parallel": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "queue_length": {
        "min": 5,
        "max": 100,
        "default": 10
      }
    }
  }
}

Parameters

Name In Type Required Description
tenant_id path string true Tenant identifier.
If-Match header string false Contains the config' current ETag, and performs the update only if it matches the one stored in the database.
body body Configuration true Configuration update.

Example responses

400 Response

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

Responses

Status Meaning Description Schema
204 No Content Configuration updated. None
400 Bad Request The request body is malformed. Error
401 Unauthorized The user cannot be granted authentication. Error
412 Precondition Failed Document with a matching ETag does not exist. None
500 Internal Server Error Internal server error. Error

Update Delta Job Status

Code samples

# You can also use wget
curl -X PUT http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/delta/{job_id}/status \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

PUT http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/delta/{job_id}/status HTTP/1.1
Host: mender-deployments:8080
Content-Type: application/json
Accept: application/json

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

fetch('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/delta/{job_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'
}

result = RestClient.put 'http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/delta/{job_id}/status',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.put('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/delta/{job_id}/status', 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','http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/delta/{job_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("http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/delta/{job_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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/delta/{job_id}/status", data)
    req.Header = headers

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

PUT /tenants/{tenant_id}/delta/{job_id}/status

Update status of generate delta job

Generate delta worker uses this endpoint to report back generate delta job status.

Body parameter

{
  "status": "success"
}

Parameters

Name In Type Required Description
tenant_id path string true Tenant identifier.
job_id path string true Job identifier.
body body GenerateDeltaJobStatus true New job status.

Example responses

400 Response

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

Responses

Status Meaning Description Schema
204 No Content Status updated sucessfully. None
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error

Get last device deployment status

Code samples

# You can also use wget
curl -X POST http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/devices/deployments/last \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/devices/deployments/last HTTP/1.1
Host: mender-deployments:8080
Content-Type: application/json
Accept: application/json

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

fetch('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/devices/deployments/last',
{
  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 'http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/devices/deployments/last',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/devices/deployments/last', 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','http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/devices/deployments/last', 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("http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/devices/deployments/last");
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", "http://mender-deployments:8080/api/internal/v1/deployments/tenants/{tenant_id}/devices/deployments/last", data)
    req.Header = headers

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

POST /tenants/{tenant_id}/devices/deployments/last

Get status of the last device devployment

Return the status of the last unsucessful device deployment.

Body parameter

{
  "device_ids": [
    "string"
  ]
}

Parameters

Name In Type Required Description
tenant_id path string true Tenant identifier.
body body LastDeviceDeploymentReq true

Example responses

200 Response

{
  "device_deployment_last_statuses": [
    {
      "device_id": "b86dfe3d-a0a6-4838-b374-5fbcb7c956a1",
      "deployment_id": "acaf62f0-6a6f-45e4-9c52-838ee593cb62",
      "device_deployment_id": "b14a36d3-c1a9-408c-b128-bfb4808604f1",
      "device_deployment_status": "success"
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK List of device deployment statuses returned. LastDeviceDeploymentsStatuses
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error

Schemas

NewTenant

{
  "tenant_id": "58be8208dd77460001fe0d78"
}

New tenant descriptor.

Properties
Name Type Required Description
tenant_id string false New tenant's ID.

Error

{
  "error": "error message",
  "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).

StorageSettings

{
  "region": "us-east-1",
  "bucket": "mender-artifacts-unique-bucket-name",
  "uri": "example.internal:9000",
  "external_uri": "example.com",
  "key": "<key>",
  "secret": "<secret>",
  "token": "<token>",
  "force_path_style": false,
  "use_accelerate": false
}

Per tenant storage settings.

Properties
Name Type Required Description
type string false The storage provider type 'azure' Blob storage or AWS 's3' (defaults to s3).
region string false AWS region (S3 only: required).
bucket string true S3 Bucket (Azure: container) name.
uri string false Bucket/container endpoint URI.
external_uri string false Public Endpoint URI for presigning URLs (S3 only).
key string true Access key identifier (Azure: account name).
secret string true Secret access key (Azure: access key).
token string false AWS S3 session token (S3 only).
force_path_style boolean false Force S3 path-style instead of virtual-hosted style (S3 only).
use_accelerate boolean false Enable S3 Transfer acceleration (S3 only).
connection_string string false Shared access key connection string (Azure only).
container_name string false Alias for 'bucket' (Azure only).
account_name string false Alias for 'key' (Azure only).
account_key string false Alias for 'secret' (Azure only).
Enumerated Values
Property Value
type s3
type azure

StorageUsage

{
  "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.

StorageLimit

{
  "limit": 1073741824
}

Tenant account storage limit

Properties
Name Type Required Description
limit integer true Storage limit in bytes. If set to 0 - there is no limit for storage.

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"
}

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 false
artifacts [string] false An array of artifact's identifiers.
type string false
Enumerated Values
Property Value
status inprogress
status pending
status finished
type configuration
type software

NewConfigurationDeployment

{
  "name": "config-1.1",
  "configuration": "{\"foo\":\"bar\"}"
}

Properties
Name Type Required Description Plans
name string true Name of the deployment
configuration string true A string containing a configuration object.
The deployments service will use it to generate configuration
artifact for the device.
The artifact will be generated when the device will ask
for an update.
retries integer false The number of times a device can retry the deployment
in case of failure, defaults to 0.
update_control_map object false A valid JSON object defining the update control map.
NOTE: Available only in the Enterprise plan.
enterprise

XDeltaArgs

{
  "disable_checksum": false,
  "disable_external_decompression": false,
  "compression_level": 6,
  "source_window_size": 0,
  "input_window_size": 0,
  "compression_duplicates_window": 0,
  "instruction_buffer_size": 0
}

xdelta3 arguments. Please refer to the xdelta3 documentation for a detailed description of the different options.

Properties
Name Type Required Description
disable_checksum boolean false Disables checksum
disable_external_decompression boolean false Disable external decompression
compression_level number(integer) false Compression level
source_window_size number(integer) false Source window size
input_window_size number(integer) false Input window size
compression_duplicates_window number(integer) false Compression duplicates window
instruction_buffer_size number(integer) false Instruction buffer size

XDeltaArgsLimits

{
  "compression_level": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "source_window_size": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "input_window_size": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "compression_duplicates_window": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "instruction_buffer_size": {
    "min": 5,
    "max": 100,
    "default": 10
  }
}

Limits for arguments which will be passed to xdelta3. Please refer to the xdelta3 documentation for a detailed description of the different options.

Properties
Name Type Required Description
compression_level Limit false Limit for compression level.
source_window_size Limit false Limit for source window size.
input_window_size Limit false Limit for input window size limit.
compression_duplicates_window Limit false Limit for compression duplicates window.
instruction_buffer_size Limit false Limit for instruction buffer size.

BinaryDeltaConfiguration

{
  "xdelta_args": {
    "disable_checksum": false,
    "disable_external_decompression": false,
    "compression_level": 6,
    "source_window_size": 0,
    "input_window_size": 0,
    "compression_duplicates_window": 0,
    "instruction_buffer_size": 0
  },
  "timeout": 0
}

The mender-binary-delta-generator configuration options.

Properties
Name Type Required Description
xdelta_args XDeltaArgs false xdelta3 arguments. Please refer to the xdelta3 documentation
for a detailed description of the different options.
timeout number(integer) false Delta generation job timeout in seconds.

BinaryDeltaLimits

{
  "xdelta_args_limits": {
    "compression_level": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "source_window_size": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "input_window_size": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "compression_duplicates_window": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "instruction_buffer_size": {
      "min": 5,
      "max": 100,
      "default": 10
    }
  },
  "timeout": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "jobs_in_parallel": {
    "min": 5,
    "max": 100,
    "default": 10
  },
  "queue_length": {
    "min": 5,
    "max": 100,
    "default": 10
  }
}

The mender-binary-delta-generator configuration limits.

Properties
Name Type Required Description
xdelta_args_limits XDeltaArgsLimits false Limits for arguments which will be passed to xdelta3.
Please refer to the xdelta3 documentation
for a detailed description of the different options.
timeout Limit false Limit descriptor.
jobs_in_parallel Limit false Maximum number of delta generation jobs which can be run in parallel.
queue_length Limit false Maximum number of queued delta generation jobs.

DeltaConfiguration

{
  "enabled": true,
  "binary_delta": {
    "xdelta_args": {
      "disable_checksum": false,
      "disable_external_decompression": false,
      "compression_level": 6,
      "source_window_size": 0,
      "input_window_size": 0,
      "compression_duplicates_window": 0,
      "instruction_buffer_size": 0
    },
    "timeout": 0
  },
  "binary_delta_limits": {
    "xdelta_args_limits": {
      "compression_level": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "source_window_size": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "input_window_size": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "compression_duplicates_window": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "instruction_buffer_size": {
        "min": 5,
        "max": 100,
        "default": 10
      }
    },
    "timeout": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "jobs_in_parallel": {
      "min": 5,
      "max": 100,
      "default": 10
    },
    "queue_length": {
      "min": 5,
      "max": 100,
      "default": 10
    }
  }
}

Delta configuration options.

Properties
Name Type Required Description
enabled boolean false
binary_delta BinaryDeltaConfiguration false The mender-binary-delta-generator configuration options.
binary_delta_limits BinaryDeltaLimits false The mender-binary-delta-generator configuration limits.

Configuration

{
  "delta": {
    "enabled": true,
    "binary_delta": {
      "xdelta_args": {
        "disable_checksum": false,
        "disable_external_decompression": false,
        "compression_level": 6,
        "source_window_size": 0,
        "input_window_size": 0,
        "compression_duplicates_window": 0,
        "instruction_buffer_size": 0
      },
      "timeout": 0
    },
    "binary_delta_limits": {
      "xdelta_args_limits": {
        "compression_level": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "source_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "input_window_size": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "compression_duplicates_window": {
          "min": 5,
          "max": 100,
          "default": 10
        },
        "instruction_buffer_size": {
          "min": 5,
          "max": 100,
          "default": 10
        }
      },
      "timeout": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "jobs_in_parallel": {
        "min": 5,
        "max": 100,
        "default": 10
      },
      "queue_length": {
        "min": 5,
        "max": 100,
        "default": 10
      }
    }
  }
}

Tenant specific configuration.

Properties
Name Type Required Description
delta DeltaConfiguration false Delta configuration options.

Limit

{
  "min": 5,
  "max": 100,
  "default": 10
}

Limit descriptor.

Properties
Name Type Required Description
min number false Minimum value.
max number false Maximum value.
default number false Default value.

GenerateDeltaJobStatus

{
  "status": "success"
}

Status of the generate delta job.

Properties
Name Type Required Description
status string false

DeviceDeployment

{
  "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
  "deployment": {
    "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
    "name": "production",
    "artifact_name": "Application 0.0.1",
    "status": "inprogress",
    "created": "2016-02-11T13:03:17.063493443Z",
    "device_count": 100
  },
  "device": {
    "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
    "device_type": "Raspberry Pi 3",
    "status": "installing",
    "finished": "2016-03-11T13:03:17.063493443Z",
    "created": "2016-02-11T13:03:17.063493443Z",
    "state": "installing",
    "substate": "installing.enter;script:foo-bar",
    "log": false,
    "image": {
      "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
      "name": "Application 1.0.0",
      "meta": {
        "description": "Johns Monday test build"
      },
      "meta_artifact": {
        "name": "Application 1.0.0",
        "device_types_compatible": [
          "Beagle Bone"
        ],
        "info": {
          "format": "mender",
          "version": 3
        },
        "signed": false,
        "updates": [
          {
            "type_info": {
              "type": "rootfs-image"
            },
            "files": [
              {
                "name": "rootfs-image-1",
                "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
                "size": 123,
                "date": "2016-03-11T13:03:17.063+0000"
              }
            ],
            "meta_data": {}
          }
        ],
        "artifact_provides": {
          "artifact_name": "test",
          "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
          "rootfs-image.version": "test"
        },
        "artifact_depends": {
          "device_type": [
            "test"
          ]
        },
        "clears_artifact_provides": [
          "rootfs-image.*"
        ]
      },
      "size": 36891648,
      "modified": "2016-03-11T13:03:17.063493443Z"
    }
  }
}

Properties
Name Type Required Description
id string false
deployment Deployment true
device DeviceWithImage true

DeviceWithImage

{
  "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",
  "image": {
    "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
    "name": "Application 1.0.0",
    "meta": {
      "description": "Johns Monday test build"
    },
    "meta_artifact": {
      "name": "Application 1.0.0",
      "device_types_compatible": [
        "Beagle Bone"
      ],
      "info": {
        "format": "mender",
        "version": 3
      },
      "signed": false,
      "updates": [
        {
          "type_info": {
            "type": "rootfs-image"
          },
          "files": [
            {
              "name": "rootfs-image-1",
              "checksum": "cc436f982bc60a8255fe1926a450db5f195a19ad",
              "size": 123,
              "date": "2016-03-11T13:03:17.063+0000"
            }
          ],
          "meta_data": {}
        }
      ],
      "artifact_provides": {
        "artifact_name": "test",
        "rootfs-image.checksum": "32714818ad6f98ee0185a52e23a475d89122e3efd2b2c26c733781c28e798c99",
        "rootfs-image.version": "test"
      },
      "artifact_depends": {
        "device_type": [
          "test"
        ]
      },
      "clears_artifact_provides": [
        "rootfs-image.*"
      ]
    },
    "size": 36891648,
    "modified": "2016-03-11T13:03:17.063493443Z"
  }
}

Properties
Name Type Required Description
id string true Device identifier.
status DeviceStatus true
created string(date-time) false
finished string(date-time) false
deleted 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
image object false
» id string false Image ID
» meta object false
»» description string false Image description
» meta_artifact object false
»» name string false
»» device_types_compatible [string] false An array of compatible device types.
»» info ArtifactInfo false Information about artifact format and version.
»» signed boolean false Idicates if artifact is signed or not.
»» updates [Update] false [Single updated to be applied.
]
»» artifact_provides object false List of Artifact provides.

Map of key/value pairs, where both keys and values are strings.
»»» additionalProperties string false
»» artifact_depends object false List of Artifact depends.

Map of key/value pairs, where keys are strings and values are lists of strings.
»»» additionalProperties [string] false
»» clears_artifact_provides [string] false List of Clear Artifact provides.
» size integer false Image size in bytes
» modified string(date-time) false Creation / last edition of any of the artifact properties

DeviceStatus

"failure"

Properties
Name Type Required Description
anonymous string false
Enumerated Values
Property Value
anonymous failure
anonymous aborted
anonymous pause_before_installing
anonymous pause_before_committing
anonymous pause_before_rebooting
anonymous downloading
anonymous installing
anonymous rebooting
anonymous pending
anonymous success
anonymous noartifact
anonymous already-installed
anonymous decommissioned

ArtifactTypeInfo

{
  "type": "string"
}

Information about update type.

Properties
Name Type Required Description
type string false Note that for emtpy Artifacts, the type is 'null'

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

LastDeviceDeploymentsStatuses

{
  "device_deployment_last_statuses": [
    {
      "device_id": "b86dfe3d-a0a6-4838-b374-5fbcb7c956a1",
      "deployment_id": "acaf62f0-6a6f-45e4-9c52-838ee593cb62",
      "device_deployment_id": "b14a36d3-c1a9-408c-b128-bfb4808604f1",
      "device_deployment_status": "success"
    }
  ]
}

Properties
Name Type Required Description
device_deployment_last_statuses [LastDeviceDeployment] true

LastDeviceDeployment

{
  "device_id": "b86dfe3d-a0a6-4838-b374-5fbcb7c956a1",
  "deployment_id": "acaf62f0-6a6f-45e4-9c52-838ee593cb62",
  "device_deployment_id": "b14a36d3-c1a9-408c-b128-bfb4808604f1",
  "device_deployment_status": "success"
}

Properties
Name Type Required Description
device_id string false
deployment_id string false
device_deployment_id string false
device_deployment_status string false

LastDeviceDeploymentReq

{
  "device_ids": [
    "string"
  ]
}

Properties
Name Type Required Description
device_ids [string] true

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. Not exposed via the API Gateway, internal use only.

Base URLs:

Check Liveliness

Code samples

# You can also use wget
curl -X GET http://mender-device-auth:8080/api/internal/v1/devauth/alive \
  -H 'Accept: application/json'

GET http://mender-device-auth:8080/api/internal/v1/devauth/alive HTTP/1.1
Host: mender-device-auth:8080
Accept: application/json


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

fetch('http://mender-device-auth:8080/api/internal/v1/devauth/alive',
{
  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 'http://mender-device-auth:8080/api/internal/v1/devauth/alive',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-device-auth:8080/api/internal/v1/devauth/alive', 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','http://mender-device-auth:8080/api/internal/v1/devauth/alive', 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("http://mender-device-auth:8080/api/internal/v1/devauth/alive");
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", "http://mender-device-auth:8080/api/internal/v1/devauth/alive", data)
    req.Header = headers

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

GET /alive

*Trivial endpoint that unconditionally returns an empty 204 response whenever the API handler is running correctly. *

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 Service is up and running None
500 Internal Server Error Internal API error Error

Check Health

Code samples

# You can also use wget
curl -X GET http://mender-device-auth:8080/api/internal/v1/devauth/health \
  -H 'Accept: application/json'

GET http://mender-device-auth:8080/api/internal/v1/devauth/health HTTP/1.1
Host: mender-device-auth:8080
Accept: application/json


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

fetch('http://mender-device-auth:8080/api/internal/v1/devauth/health',
{
  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 'http://mender-device-auth:8080/api/internal/v1/devauth/health',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-device-auth:8080/api/internal/v1/devauth/health', 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','http://mender-device-auth:8080/api/internal/v1/devauth/health', 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("http://mender-device-auth:8080/api/internal/v1/devauth/health");
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", "http://mender-device-auth:8080/api/internal/v1/devauth/health", data)
    req.Header = headers

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

GET /health

Check the health of the service

Example responses

Unexpected internal error

{
  "error": "internal error",
  "request_id": "ffd712be-d697-4cb7-814b-88ff1e2eb5f6"
}

Service unhealthy / not ready to accept traffic. At least one dependency is not running.

{
  "error": "error reaching MongoDB: context deadline exceeded",
  "request_id": "ffd712be-d697-4cb7-814b-88ff1e2eb5f6"
}

Responses

Status Meaning Description Schema
204 No Content Service is healthy and all dependencies are up and running. None
500 Internal Server Error Unexpected internal error Error
503 Service Unavailable Service unhealthy / not ready to accept traffic. At least one dependency is not running. Error

Verify JWT

Code samples

# You can also use wget
curl -X POST http://mender-device-auth:8080/api/internal/v1/devauth/tokens/verify \
  -H 'Accept: application/json' \
  -H 'Authorization: string'

POST http://mender-device-auth:8080/api/internal/v1/devauth/tokens/verify HTTP/1.1
Host: mender-device-auth:8080
Accept: application/json
Authorization: string


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

fetch('http://mender-device-auth:8080/api/internal/v1/devauth/tokens/verify',
{
  method: 'POST',

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

require 'rest-client'
require 'json'

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

result = RestClient.post 'http://mender-device-auth:8080/api/internal/v1/devauth/tokens/verify',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('http://mender-device-auth:8080/api/internal/v1/devauth/tokens/verify', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

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

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','http://mender-device-auth:8080/api/internal/v1/devauth/tokens/verify', 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("http://mender-device-auth:8080/api/internal/v1/devauth/tokens/verify");
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{
        "Accept": []string{"application/json"},
        "Authorization": []string{"string"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://mender-device-auth:8080/api/internal/v1/devauth/tokens/verify", data)
    req.Header = headers

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

POST /tokens/verify

Check the validity of a token

Besides the basic validity check, checks the token expiration time and user-initiated token revocation. Services which intend to use it should be correctly set up in the gateway's configuration.

Parameters

Name In Type Required Description
Authorization header string true The token in base64-encoded form.

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
200 OK The token is valid. None
400 Bad Request Missing or malformed request parameters. None
401 Unauthorized Verification failed, authentication should not be granted. None
403 Forbidden Token has expired - apply for a new one. None
500 Internal Server Error Unexpected error. Error

Revoke Device Tokens

Code samples

# You can also use wget
curl -X DELETE http://mender-device-auth:8080/api/internal/v1/devauth/tokens?tenant_id=string \
  -H 'Accept: application/json'

DELETE http://mender-device-auth:8080/api/internal/v1/devauth/tokens?tenant_id=string HTTP/1.1
Host: mender-device-auth:8080
Accept: application/json


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

fetch('http://mender-device-auth:8080/api/internal/v1/devauth/tokens?tenant_id=string',
{
  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'
}

result = RestClient.delete 'http://mender-device-auth:8080/api/internal/v1/devauth/tokens',
  params: {
  'tenant_id' => 'string'
}, headers: headers

p JSON.parse(result)

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

r = requests.delete('http://mender-device-auth:8080/api/internal/v1/devauth/tokens', params={
  'tenant_id': 'string'
}, 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('DELETE','http://mender-device-auth:8080/api/internal/v1/devauth/tokens', 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("http://mender-device-auth:8080/api/internal/v1/devauth/tokens?tenant_id=string");
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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-device-auth:8080/api/internal/v1/devauth/tokens", data)
    req.Header = headers

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

DELETE /tokens

Delete device tokens

This endpoint is designed to be used for device decommissionning and tenant account suspension purpose. For device decommissioning purpose both tenant_id and device_id parameters must be set. When both tenant_id and device_id parameters are set, all tokens will be deleted for device with given device_id. For tenant account suspension purpose only tenant_id parameter must be set. When device_id parameter is not set (only tenant_id parameter is set) all tokens for all tenant devices will be deleted.

Parameters

Name In Type Required Description
tenant_id query string true Tenant ID.
device_id query string false Device ID.

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 Tokens deleted. None
400 Bad Request Invalid parameters. See error message for details. Error
500 Internal Server Error Internal server error. Error

Get Device Limit

Code samples

# You can also use wget
curl -X GET http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices \
  -H 'Accept: application/json'

GET http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices HTTP/1.1
Host: mender-device-auth:8080
Accept: application/json


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

fetch('http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/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'
}

result = RestClient.get 'http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices', 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','http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/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("http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices", data)
    req.Header = headers

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

GET /tenant/{tenant_id}/limits/max_devices

Max device count limit

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.

Example responses

200 Response

{
  "limit": 123
}

Responses

Status Meaning Description Schema
200 OK Successful response. Limit
400 Bad Request Invalid parameters. See error message for details. Error
500 Internal Server Error Internal server error. Error

Update Device Limit

Code samples

# You can also use wget
curl -X PUT http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

PUT http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices HTTP/1.1
Host: mender-device-auth:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "limit": 123
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices',
{
  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 'http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.put('http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices', 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','http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/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("http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices");
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", "http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices", data)
    req.Header = headers

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

PUT /tenant/{tenant_id}/limits/max_devices

Update max device count limit

Body parameter

{
  "limit": 123
}

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.
body body Limit true

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 Limit information updated. None
400 Bad Request The request body is malformed. Error
500 Internal Server Error Internal server error. Error

Clear Device Limit

Code samples

# You can also use wget
curl -X DELETE http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices \
  -H 'Accept: application/json'

DELETE http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices HTTP/1.1
Host: mender-device-auth:8080
Accept: application/json


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

fetch('http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices',
{
  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'
}

result = RestClient.delete 'http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.delete('http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices', 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('DELETE','http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/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("http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_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{
        "Accept": []string{"application/json"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-device-auth:8080/api/internal/v1/devauth/tenant/{tenant_id}/limits/max_devices", data)
    req.Header = headers

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

DELETE /tenant/{tenant_id}/limits/max_devices

Remove max device count limit

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.

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 Limit information deleted. None
500 Internal Server Error Internal server error. Error

Create Tenant

Code samples

# You can also use wget
curl -X POST http://mender-device-auth:8080/api/internal/v1/devauth/tenants \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-device-auth:8080/api/internal/v1/devauth/tenants HTTP/1.1
Host: mender-device-auth:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "tenant_id": "58be8208dd77460001fe0d78"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-device-auth:8080/api/internal/v1/devauth/tenants',
{
  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 'http://mender-device-auth:8080/api/internal/v1/devauth/tenants',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('http://mender-device-auth:8080/api/internal/v1/devauth/tenants', 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','http://mender-device-auth:8080/api/internal/v1/devauth/tenants', 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("http://mender-device-auth:8080/api/internal/v1/devauth/tenants");
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", "http://mender-device-auth:8080/api/internal/v1/devauth/tenants", data)
    req.Header = headers

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

POST /tenants

Provision a new tenant

Sets up all tenant-related infrastructure, e.g. a migrated tenant's database.

Body parameter

{
  "tenant_id": "58be8208dd77460001fe0d78"
}

Parameters

Name In Type Required Description
body body NewTenant true New tenant descriptor.

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
201 Created Tenant was successfully provisioned. None
400 Bad Request Bad request. None
500 Internal Server Error Internal server error. Error

Delete Device

Code samples

# You can also use wget
curl -X DELETE http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did} \
  -H 'Accept: application/json'

DELETE http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did} HTTP/1.1
Host: mender-device-auth:8080
Accept: application/json


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

fetch('http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}',
{
  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'
}

result = RestClient.delete 'http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.delete('http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}', 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('DELETE','http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}', 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("http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}");
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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}", data)
    req.Header = headers

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

DELETE /tenants/{tid}/devices/{did}

Delete a device from deviceauth service.

Parameters

Name In Type Required Description
tid path string true Tenant identifier.
did path string true 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
201 Created Device deleted successfully. None
400 Bad Request Bad request. None
500 Internal Server Error Internal server error. Error

Set external identity

Code samples

# You can also use wget
curl -X PUT http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}/external \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

PUT http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}/external HTTP/1.1
Host: mender-device-auth:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "id": "string",
  "name": "string",
  "provider": "string",
  "id_data": "string"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}/external',
{
  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 'http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}/external',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.put('http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}/external', 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','http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}/external', 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("http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}/external");
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", "http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}/external", data)
    req.Header = headers

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

PUT /tenants/{tid}/devices/{did}/external

Replace the external identity of a device.

Body parameter

{
  "id": "string",
  "name": "string",
  "provider": "string",
  "id_data": "string"
}

Parameters

Name In Type Required Description
tid path string true Tenant identifier.
did path string true Device identifier.
body body ExternalDevice true External device descriptor.

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 identity updated successfully. None
400 Bad Request Bad request. None
500 Internal Server Error Internal server error. Error

Delete Tenant

Code samples

# You can also use wget
curl -X DELETE http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid} \
  -H 'Accept: application/json'

DELETE http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid} HTTP/1.1
Host: mender-device-auth:8080
Accept: application/json


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

fetch('http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}',
{
  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'
}

result = RestClient.delete 'http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.delete('http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}', 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('DELETE','http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}', 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("http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}");
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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}", data)
    req.Header = headers

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

DELETE /tenants/{tid}

Delete all the data for given tenant.

Parameters

Name In Type Required Description
tid path string true Tenant ID.

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 All the tenant data have been successfully deleted. None
500 Internal Server Error Internal Server Error on delete. Error

Device Status

Code samples

# You can also use wget
curl -X GET http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}/status \
  -H 'Accept: application/json'

GET http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}/status HTTP/1.1
Host: mender-device-auth:8080
Accept: application/json


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

fetch('http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}/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'
}

result = RestClient.get 'http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}/status',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}/status', 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','http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}/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("http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/{did}/status", data)
    req.Header = headers

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

GET /tenants/{tid}/devices/{did}/status

Get the status of a tenant's device

Returns the overall status of the device, computed over the statuses of its various authsets.

Parameters

Name In Type Required Description
tid path string true Tenant identifier.
did path string true Device identifier.

Example responses

200 Response

{
  "status": "accepted"
}

Responses

Status Meaning Description Schema
200 OK Success. Status
400 Bad Request Invalid parameters. See error message for details. Error
404 Not Found Tenant or device not found. Error
500 Internal Server Error Internal server error. Error

List Devices

Code samples

# You can also use wget
curl -X GET http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices \
  -H 'Accept: application/json'

GET http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices HTTP/1.1
Host: mender-device-auth:8080
Accept: application/json


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

fetch('http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/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'
}

result = RestClient.get 'http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices', 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','http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/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("http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices", data)
    req.Header = headers

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

GET /tenants/{tid}/devices

Get a list of tenant's devices.

Provides a list of tenant's devices, sorted by creation date, with optional device status filter.

Parameters

Name In Type Required Description
tid path string true Tenant identifier.
status query string false Device status filter. If not specified, all devices are listed.
id query array[string] false Device ID filter. Can be repeated to query a set of devices.
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": "string",
    "updated_ts": "string",
    "check_in_time": "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": "string"
      }
    ],
    "decommissioning": true,
    "external_id": {
      "data": "iot-hub device-id/module-id",
      "active": 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(datetime) false Created timestamp
» updated_ts string(datetime) false Updated timestamp
» check_in_time string(date-time) false Time when accepted device contacted server for the last time.
» 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(datetime) false Created timestamp
» decommissioning boolean false Devices that are part of ongoing decommissioning process will return True
» external_id ExternalIdentity false Device external identity.
»» data string false External identity.
»» active boolean false Status flag.
Enumerated Values
Property Value
status pending
status accepted
status rejected
status preauthorized
status noauth
status pending
status accepted
status rejected
status preauthorized
Response Headers
Status Header Type Format Description
200 Link string Standard header, we support 'first', 'next', and 'prev'.

Count Devices

Code samples

# You can also use wget
curl -X GET http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/count \
  -H 'Accept: application/json'

GET http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/count HTTP/1.1
Host: mender-device-auth:8080
Accept: application/json


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

fetch('http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/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'
}

result = RestClient.get 'http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/count',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/count', 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','http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/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("http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-device-auth:8080/api/internal/v1/devauth/tenants/{tid}/devices/count", data)
    req.Header = headers

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

GET /tenants/{tid}/devices/count

Count number of devices, optionally filtered by status.

Parameters

Name In Type Required Description
tid path string true Tenant identifier.
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

Schemas

NewTenant

{
  "tenant_id": "58be8208dd77460001fe0d78"
}

New tenant descriptor.

Properties
Name Type Required Description
tenant_id string false New tenant's ID.

Limit

{
  "limit": 123
}

Tenant account limit.

Properties
Name Type Required Description
limit integer true

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).

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
status noauth

Device

{
  "id": "string",
  "identity_data": {
    "mac": "00:01:02:03:04:05",
    "sku": "My Device 1",
    "sn": "SN1234567890"
  },
  "status": "pending",
  "created_ts": "string",
  "updated_ts": "string",
  "check_in_time": "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": "string"
    }
  ],
  "decommissioning": true,
  "external_id": {
    "data": "iot-hub device-id/module-id",
    "active": 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(datetime) false Created timestamp
updated_ts string(datetime) false Updated timestamp
check_in_time string(date-time) false Time when accepted device contacted server for the last time.
auth_sets [AuthSet] false [Authentication data set]
decommissioning boolean false Devices that are part of ongoing decommissioning process will return True
external_id ExternalIdentity false Device external identity.
Enumerated Values
Property Value
status pending
status accepted
status rejected
status preauthorized
status noauth

ExternalDevice

{
  "id": "string",
  "name": "string",
  "provider": "string",
  "id_data": "string"
}

External device descriptor

Properties
Name Type Required Description
id string true ID assigned by external provider
name string true Name of the device
provider string true Name of the external provider
id_data string false Optional custom ID data

AuthSet

{
  "id": "string",
  "pubkey": "string",
  "identity_data": {
    "mac": "00:01:02:03:04:05",
    "sku": "My Device 1",
    "sn": "SN1234567890"
  },
  "status": "pending",
  "ts": "string"
}

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(datetime) false Created timestamp
Enumerated Values
Property Value
status pending
status accepted
status rejected
status preauthorized

Count

{
  "count": 42
}

Counter type

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

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.

ExternalIdentity

{
  "data": "iot-hub device-id/module-id",
  "active": true
}

Device external identity.

Properties
Name Type Required Description
data string false External identity.
active boolean false Status flag.

Device configure

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

Internal API for managing persistent device connections. Intended for use by the web GUI.

Base URLs:

Check Health

Code samples

# You can also use wget
curl -X GET http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/health \
  -H 'Accept: application/json'

GET http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/health HTTP/1.1
Host: mender-deviceconfig:8080
Accept: application/json


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

fetch('http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/health',
{
  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 'http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/health',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/health', 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','http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/health', 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("http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/health");
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", "http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/health", data)
    req.Header = headers

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

GET /health

Get health status of service

Example responses

400 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content Service is healthy. None
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error

Check Liveliness

Code samples

# You can also use wget
curl -X GET http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/alive \
  -H 'Accept: application/json'

GET http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/alive HTTP/1.1
Host: mender-deviceconfig:8080
Accept: application/json


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

fetch('http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/alive',
{
  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 'http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/alive',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/alive', 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','http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/alive', 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("http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/alive");
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", "http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/alive", data)
    req.Header = headers

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

GET /alive

Get service liveliness status.

Example responses

500 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content Service is up and serving requests. None
500 Internal Server Error Internal Server Error. Error

Provision tenant

Code samples

# You can also use wget
curl -X POST http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants HTTP/1.1
Host: mender-deviceconfig:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "tenant_id": "string"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants',
{
  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 'http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants', 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','http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants', 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("http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants");
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", "http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants", data)
    req.Header = headers

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

POST /tenants

Initialize internal state for a new tenant

Body parameter

{
  "tenant_id": "string"
}

Parameters

Name In Type Required Description
body body NewTenant false

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
201 Created Tenant initialized successfully. None
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error

Delete Tenant

Code samples

# You can also use wget
curl -X DELETE http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId} \
  -H 'Accept: application/json'

DELETE http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId} HTTP/1.1
Host: mender-deviceconfig:8080
Accept: application/json


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

fetch('http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}',
{
  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'
}

result = RestClient.delete 'http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.delete('http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}', 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('DELETE','http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}', 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("http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}");
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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}", data)
    req.Header = headers

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

DELETE /tenants/{tenantId}

Delete all the data for given tenant.

Parameters

Name In Type Required Description
tenantId path string true ID of tenant.

Example responses

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content All the tenant data have been successfully deleted. None
500 Internal Server Error Internal Server Error. Error

Provision device

Code samples

# You can also use wget
curl -X POST http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/devices \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/devices HTTP/1.1
Host: mender-deviceconfig:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/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'
}

result = RestClient.post 'http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/devices',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/devices', 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','http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/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("http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/devices", data)
    req.Header = headers

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

POST /tenants/{tenantId}/devices

Register a new device with the deviceconfig service.

Body parameter

{
  "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940"
}

Parameters

Name In Type Required Description
tenantId path string true ID of tenant the device belongs to.
body body NewDevice false

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
201 Created Device was provisioned successfully. None
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error

Decommission device

Code samples

# You can also use wget
curl -X DELETE http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/devices/{deviceId} \
  -H 'Accept: application/json'

DELETE http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/devices/{deviceId} HTTP/1.1
Host: mender-deviceconfig:8080
Accept: application/json


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

fetch('http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/devices/{deviceId}',
{
  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'
}

result = RestClient.delete 'http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/devices/{deviceId}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.delete('http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/devices/{deviceId}', 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('DELETE','http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/devices/{deviceId}', 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("http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/devices/{deviceId}");
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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/devices/{deviceId}", data)
    req.Header = headers

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

DELETE /tenants/{tenantId}/devices/{deviceId}

Remove a device from the deviceconfig service.

Parameters

Name In Type Required Description
tenantId path string true ID of tenant the device belongs to.
deviceId path string true ID of the target device.

Example responses

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content Device was deleted successfully None
500 Internal Server Error Internal Server Error. Error

Deploy Device Configuration

Code samples

# You can also use wget
curl -X POST http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/configurations/device/{deviceId}/deploy \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/configurations/device/{deviceId}/deploy HTTP/1.1
Host: mender-deviceconfig:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "retries": 0,
  "update_control_map": {}
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/configurations/device/{deviceId}/deploy',
{
  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 'http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/configurations/device/{deviceId}/deploy',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/configurations/device/{deviceId}/deploy', 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','http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/configurations/device/{deviceId}/deploy', 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("http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/configurations/device/{deviceId}/deploy");
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", "http://mender-deviceconfig:8080/api/internal/v1/deviceconfig/tenants/{tenantId}/configurations/device/{deviceId}/deploy", data)
    req.Header = headers

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

POST /tenants/{tenantId}/configurations/device/{deviceId}/deploy

Deploy the device's configuration

Body parameter

{
  "retries": 0,
  "update_control_map": {}
}

Parameters

Name In Type Required Description
deviceId path string true ID of the device.
tenantId path string true ID of the tenant.
body body NewConfigurationDeployment false

Example responses

200 Response

{
  "deployment_id": "string"
}

Responses

Status Meaning Description Schema
200 OK Success NewConfigurationDeploymentResponse
400 Bad Request Bad Request. Error
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

Schemas

Error

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.
request_id string false Request ID passed with the request X-MEN-RequestID header or generated by the server.

NewTenant

{
  "tenant_id": "string"
}

Properties
Name Type Required Description
tenant_id string true ID of new tenant.

NewDevice

{
  "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940"
}

Properties
Name Type Required Description
device_id string(uuid) true ID of the new device.

NewConfigurationDeployment

{
  "retries": 0,
  "update_control_map": {}
}

Properties
Name Type Required Description Plans
retries integer false The number of times a device can retry the deployment in case of failure, defaults to 0
update_control_map object false A valid JSON object defining the update control map.
NOTE: Available only in the Enterprise plan.
enterprise

NewConfigurationDeploymentResponse

{
  "deployment_id": "string"
}

Properties
Name Type Required Description
deployment_id string false Deployment ID

Device connect

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

Internal API for managing persistent device connections. Intended for use by the web GUI.

Base URLs:

Check Health

Code samples

# You can also use wget
curl -X GET http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/health \
  -H 'Accept: application/json'

GET http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/health HTTP/1.1
Host: mender-deviceconnect:8080
Accept: application/json


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

fetch('http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/health',
{
  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 'http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/health',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/health', 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','http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/health', 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("http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/health");
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", "http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/health", data)
    req.Header = headers

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

GET /health

Get health status of service

Example responses

400 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content Service is healthy. None
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error

Check Liveliness

Code samples

# You can also use wget
curl -X GET http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/alive \
  -H 'Accept: application/json'

GET http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/alive HTTP/1.1
Host: mender-deviceconnect:8080
Accept: application/json


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

fetch('http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/alive',
{
  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 'http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/alive',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/alive', 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','http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/alive', 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("http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/alive");
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", "http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/alive", data)
    req.Header = headers

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

GET /alive

Get service liveliness status.

Example responses

500 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content Service is up and serving requests. None
500 Internal Server Error Internal Server Error. Error

Shutdown

Code samples

# You can also use wget
curl -X GET http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/shutdown \
  -H 'Accept: application/json'

GET http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/shutdown HTTP/1.1
Host: mender-deviceconnect:8080
Accept: application/json


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

fetch('http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/shutdown',
{
  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 'http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/shutdown',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/shutdown', 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','http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/shutdown', 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("http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/shutdown");
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", "http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/shutdown", data)
    req.Header = headers

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

GET /shutdown

Shutdown the service.

Example responses

500 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
202 Accepted The service started the graceful shutdown procedure. None
500 Internal Server Error Internal Server Error. Error

Delete Tenant

Code samples

# You can also use wget
curl -X DELETE http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId} \
  -H 'Accept: application/json'

DELETE http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId} HTTP/1.1
Host: mender-deviceconnect:8080
Accept: application/json


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

fetch('http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}',
{
  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'
}

result = RestClient.delete 'http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.delete('http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}', 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('DELETE','http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}', 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("http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}");
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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}", data)
    req.Header = headers

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

DELETE /tenants/{tenantId}

Delete all the data for given tenant.

Parameters

Name In Type Required Description
tenantId path string true ID of tenant.

Example responses

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content All the tenant data have been successfully deleted. None
500 Internal Server Error Internal Server Error. Error

Provision device

Code samples

# You can also use wget
curl -X POST http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices HTTP/1.1
Host: mender-deviceconnect:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/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'
}

result = RestClient.post 'http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices', 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','http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/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("http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices", data)
    req.Header = headers

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

POST /tenants/{tenantId}/devices

Register a new device with the deviceconnect service.

Body parameter

{
  "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940"
}

Parameters

Name In Type Required Description
tenantId path string true ID of tenant the device belongs to.
body body Device false

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
201 Created Device was provisioned successfully. None
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error

Decomission device

Code samples

# You can also use wget
curl -X DELETE http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId} \
  -H 'Accept: application/json'

DELETE http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId} HTTP/1.1
Host: mender-deviceconnect:8080
Accept: application/json


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

fetch('http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}',
{
  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'
}

result = RestClient.delete 'http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.delete('http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}', 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('DELETE','http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}', 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("http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}");
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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}", data)
    req.Header = headers

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

DELETE /tenants/{tenantId}/devices/{deviceId}

Remove a device from the deviceconnect service.

Parameters

Name In Type Required Description
tenantId path string true ID of tenant the device belongs to.
deviceId path string true ID of the target device.

Example responses

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
202 Accepted Device was deleted successfully None
500 Internal Server Error Internal Server Error. Error

Check Update

Code samples

# You can also use wget
curl -X POST http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}/check-update \
  -H 'Accept: application/json'

POST http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}/check-update HTTP/1.1
Host: mender-deviceconnect:8080
Accept: application/json


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

fetch('http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}/check-update',
{
  method: 'POST',

  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.post 'http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}/check-update',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}/check-update', 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('POST','http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}/check-update', 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("http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}/check-update");
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{
        "Accept": []string{"application/json"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}/check-update", data)
    req.Header = headers

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

POST /tenants/{tenantId}/devices/{deviceId}/check-update

Trigger check-update for the Mender client running on the device

Parameters

Name In Type Required Description
tenantId path string true ID of tenant the device belongs to.
deviceId path string true ID for the target device.

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

404 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
202 Accepted Accepted None
400 Bad Request Invalid Request. Error
404 Not Found Device not found. Error
409 Conflict Device not connected. Error
500 Internal Server Error Internal Server Error. Error

Send Inventory

Code samples

# You can also use wget
curl -X POST http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}/send-inventory \
  -H 'Accept: application/json'

POST http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}/send-inventory HTTP/1.1
Host: mender-deviceconnect:8080
Accept: application/json


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

fetch('http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}/send-inventory',
{
  method: 'POST',

  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.post 'http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}/send-inventory',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}/send-inventory', 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('POST','http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}/send-inventory', 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("http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}/send-inventory");
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{
        "Accept": []string{"application/json"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://mender-deviceconnect:8080/api/internal/v1/deviceconnect/tenants/{tenantId}/devices/{deviceId}/send-inventory", data)
    req.Header = headers

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

POST /tenants/{tenantId}/devices/{deviceId}/send-inventory

Trigger send-inventory for the Mender client running on the device

Parameters

Name In Type Required Description
tenantId path string true ID of tenant the device belongs to.
deviceId path string true ID for the target device.

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

404 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
202 Accepted Accepted None
400 Bad Request Invalid Request. Error
404 Not Found Device not found. Error
409 Conflict Device not connected. Error
500 Internal Server Error Internal Server Error. Error

Schemas

Error

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.
request_id string false Request ID passed with the request X-MEN-RequestID header or generated by the server.

NewTenant

{
  "tenant_id": "string"
}

Properties
Name Type Required Description
tenant_id string true ID of new tenant.

Device

{
  "device_id": "3bafab7b-4400-4bcf-8e6e-09f954699940"
}

Properties
Name Type Required Description
device_id string(uuid) true ID of the new device.

Device monitor

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

Internal API for monitoring.

Base URLs:

Delete Tenant

Code samples

# You can also use wget
curl -X DELETE http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenantId} \
  -H 'Accept: application/json'

DELETE http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenantId} HTTP/1.1
Host: mender-devicemonitor:8080
Accept: application/json


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

fetch('http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenantId}',
{
  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'
}

result = RestClient.delete 'http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenantId}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.delete('http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenantId}', 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('DELETE','http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenantId}', 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("http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenantId}");
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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenantId}", data)
    req.Header = headers

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

DELETE /tenants/{tenantId}

Delete all the data for given tenant.

Parameters

Name In Type Required Description
tenantId path string true ID of tenant.

Example responses

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content All the tenant data have been successfully deleted. None
500 Internal Server Error Internal Server Error. Error

List devices and their latest alerts

Code samples

# You can also use wget
curl -X GET http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenant_id}/devices \
  -H 'Accept: application/json'

GET http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenant_id}/devices HTTP/1.1
Host: mender-devicemonitor:8080
Accept: application/json


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

fetch('http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenant_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'
}

result = RestClient.get 'http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenant_id}/devices',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenant_id}/devices', 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','http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenant_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("http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenant_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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenant_id}/devices", data)
    req.Header = headers

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

GET /tenants/{tenant_id}/devices

List the devices and their latest alerts.

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.
id query array[string] false Device ID filter. Can be repeated to query a set of devices.
page query integer false Results page number
per_page query integer false Maximum number of results per page.

Example responses

200 Response

[
  {
    "id": "eed14d55-d996-42cd-8248-e806663810a8",
    "alerts_open_count": 1,
    "alerts_total_count": 1,
    "alerts": [
      {
        "name": "mender-connect systemd service",
        "level": "CRITICAL",
        "timestamp": "2019-07-21T17:32:28Z",
        "subject": {
          "name": "mender-connect",
          "status": "not-running",
          "type": "systemd.unit"
        }
      }
    ]
  }
]

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
200 OK OK Inline
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error
Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [Device] false
» id string false
» alerts_open_count integer true
» alerts_total_count integer true
» alerts [Alert] true
»» id string(uuid) false A unique ID for the alert.
»» name string false The name of the alert.
»» device_id string true
»» level string false Alert severity level
»» subject AlertSubject true Alert subject: the description of the alert origin
»»» name string true Name of an entity that caused the alert
»»» type string true The type of executable that triggered the alert
»»» status string true Status of an entity that caused the alert
»»» details string false Additional details on the alert
»» timestamp string(date-time) true Time and date when the alert occured
Enumerated Values
Property Value
level OK
level CRITICAL

List latest alerts

Code samples

# You can also use wget
curl -X GET http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenant_id}/devices/{device_id}/alerts/latest \
  -H 'Accept: application/json'

GET http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenant_id}/devices/{device_id}/alerts/latest HTTP/1.1
Host: mender-devicemonitor:8080
Accept: application/json


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

fetch('http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenant_id}/devices/{device_id}/alerts/latest',
{
  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 'http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenant_id}/devices/{device_id}/alerts/latest',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.get('http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenant_id}/devices/{device_id}/alerts/latest', 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','http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenant_id}/devices/{device_id}/alerts/latest', 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("http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenant_id}/devices/{device_id}/alerts/latest");
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", "http://mender-devicemonitor:8080/api/internal/v1/devicemonitor/tenants/{tenant_id}/devices/{device_id}/alerts/latest", data)
    req.Header = headers

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

GET /tenants/{tenant_id}/devices/{device_id}/alerts/latest

List the latest alerts for the given device. An optional 'level_from' parameter filters the result by returning alerts with at least 'level_from' or higher severity level.

Parameters

Name In Type Required Description
device_id path string true Device ID.
tenant_id path string true Tenant ID.
level_from query string false Filter the result by having level_from or higher severity level.
Enumerated Values
Parameter Value
level_from OK
level_from CRITICAL

Example responses

200 Response

[
  {
    "name": "mender-connect systemd service",
    "level": "CRITICAL",
    "timestamp": "2019-07-21T17:32:28Z",
    "subject": {
      "name": "mender-connect",
      "status": "not-running",
      "type": "systemd.unit"
    }
  }
]

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
200 OK OK Inline
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error
Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [Alert] false
» id string(uuid) false A unique ID for the alert.
» name string false The name of the alert.
» device_id string true
» level string false Alert severity level
» subject AlertSubject true Alert subject: the description of the alert origin
»» name string true Name of an entity that caused the alert
»» type string true The type of executable that triggered the alert
»» status string true Status of an entity that caused the alert
»» details string false Additional details on the alert
» timestamp string(date-time) true Time and date when the alert occured
Enumerated Values
Property Value
level OK
level CRITICAL

Schemas

Error

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.
request_id string false Request ID passed with the request X-MEN-RequestID header or generated by the server.

Alert

{
  "name": "mender-connect systemd service",
  "level": "CRITICAL",
  "timestamp": "2019-07-21T17:32:28Z",
  "subject": {
    "name": "mender-connect",
    "status": "not-running",
    "type": "systemd.unit"
  }
}

Properties
Name Type Required Description
id string(uuid) false A unique ID for the alert.
name string false The name of the alert.
device_id string true
level string false Alert severity level
subject AlertSubject true Alert subject: the description of the alert origin
timestamp string(date-time) true Time and date when the alert occured
Enumerated Values
Property Value
level OK
level CRITICAL

AlertSubject

{
  "name": "mender-connect",
  "status": "not-running",
  "type": "systemd.unit"
}

Alert subject: the description of the alert origin

Properties
Name Type Required Description
name string true Name of an entity that caused the alert
type string true The type of executable that triggered the alert
status string true Status of an entity that caused the alert
details string false Additional details on the alert

Device

{
  "id": "eed14d55-d996-42cd-8248-e806663810a8",
  "alerts_open_count": 1,
  "alerts_total_count": 1,
  "alerts": [
    {
      "name": "mender-connect systemd service",
      "level": "CRITICAL",
      "timestamp": "2019-07-21T17:32:28Z",
      "subject": {
        "name": "mender-connect",
        "status": "not-running",
        "type": "systemd.unit"
      }
    }
  ]
}

Properties
Name Type Required Description
id string false
alerts_open_count integer true
alerts_total_count integer true
alerts [Alert] true

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. Not exposed via the API Gateway - intended for internal use only.

Base URLs:

Check Health

Code samples

# You can also use wget
curl -X GET http://mender-inventory:8080/api/internal/v1/inventory/health \
  -H 'Accept: */*'

GET http://mender-inventory:8080/api/internal/v1/inventory/health HTTP/1.1
Host: mender-inventory:8080
Accept: */*


const headers = {
  'Accept':'*/*'
};

fetch('http://mender-inventory:8080/api/internal/v1/inventory/health',
{
  method: 'GET',

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => '*/*'
}

result = RestClient.get 'http://mender-inventory:8080/api/internal/v1/inventory/health',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': '*/*'
}

r = requests.get('http://mender-inventory:8080/api/internal/v1/inventory/health', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => '*/*',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','http://mender-inventory:8080/api/internal/v1/inventory/health', 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("http://mender-inventory:8080/api/internal/v1/inventory/health");
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{"*/*"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-inventory:8080/api/internal/v1/inventory/health", data)
    req.Header = headers

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

GET /health

Check the health of the service

Example responses

500 Response

Unexpected internal error

{
  "error": "internal error",
  "request_id": "ffd712be-d697-4cb7-814b-88ff1e2eb5f6"
}

Service unhealthy / not ready to accept traffic. At least one dependency is not running.

{
  "error": "error reaching MongoDB: context deadline exceeded",
  "request_id": "ffd712be-d697-4cb7-814b-88ff1e2eb5f6"
}

Responses

Status Meaning Description Schema
204 No Content Service is healthy and all dependencies are up and running. None
500 Internal Server Error Unexpected internal error Error
503 Service Unavailable Service unhealthy / not ready to accept traffic. At least one dependency is not running. Error

Check Liveliness

Code samples

# You can also use wget
curl -X GET http://mender-inventory:8080/api/internal/v1/inventory/alive \
  -H 'Accept: */*'

GET http://mender-inventory:8080/api/internal/v1/inventory/alive HTTP/1.1
Host: mender-inventory:8080
Accept: */*


const headers = {
  'Accept':'*/*'
};

fetch('http://mender-inventory:8080/api/internal/v1/inventory/alive',
{
  method: 'GET',

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => '*/*'
}

result = RestClient.get 'http://mender-inventory:8080/api/internal/v1/inventory/alive',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': '*/*'
}

r = requests.get('http://mender-inventory:8080/api/internal/v1/inventory/alive', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => '*/*',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','http://mender-inventory:8080/api/internal/v1/inventory/alive', 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("http://mender-inventory:8080/api/internal/v1/inventory/alive");
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{"*/*"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-inventory:8080/api/internal/v1/inventory/alive", data)
    req.Header = headers

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

GET /alive

*Trivial endpoint that unconditionally returns an empty 200 response whenever the API handler is running correctly. *

Example responses

500 Response

Responses

Status Meaning Description Schema
204 No Content Service is up and running. None
500 Internal Server Error Internal API error Error

Create Tenant

Code samples

# You can also use wget
curl -X POST http://mender-inventory:8080/api/internal/v1/inventory/tenants \
  -H 'Content-Type: application/json' \
  -H 'Accept: */*'

POST http://mender-inventory:8080/api/internal/v1/inventory/tenants HTTP/1.1
Host: mender-inventory:8080
Content-Type: application/json
Accept: */*

const inputBody = '{
  "tenant_id": "1234"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'*/*'
};

fetch('http://mender-inventory:8080/api/internal/v1/inventory/tenants',
{
  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' => '*/*'
}

result = RestClient.post 'http://mender-inventory:8080/api/internal/v1/inventory/tenants',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('http://mender-inventory:8080/api/internal/v1/inventory/tenants', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

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

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','http://mender-inventory:8080/api/internal/v1/inventory/tenants', 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("http://mender-inventory:8080/api/internal/v1/inventory/tenants");
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{"*/*"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://mender-inventory:8080/api/internal/v1/inventory/tenants", data)
    req.Header = headers

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

POST /tenants

Create tenant

Create a tenant with provided configuration.

Body parameter

{
  "tenant_id": "1234"
}

Parameters

Name In Type Required Description
body body TenantNew true

Example responses

500 Response

Responses

Status Meaning Description Schema
201 Created The tenant was created successfully. None
400 Bad Request Missing or malformed request parameters. None
500 Internal Server Error Unexpected error. Error

Initialize Device

Code samples

# You can also use wget
curl -X POST http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices \
  -H 'Content-Type: application/json' \
  -H 'Accept: */*'

POST http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices HTTP/1.1
Host: mender-inventory:8080
Content-Type: application/json
Accept: */*

const inputBody = '{
  "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"
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'*/*'
};

fetch('http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/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' => '*/*'
}

result = RestClient.post 'http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

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

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_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("http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/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{"*/*"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices", data)
    req.Header = headers

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

POST /tenants/{tenant_id}/devices

Create a device resource with the supplied set of attributes

Body parameter

{
  "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"
    }
  ]
}

Parameters

Name In Type Required Description
tenant_id path string true ID of given tenant.
body body DeviceNew true

Example responses

400 Response

Responses

Status Meaning Description Schema
201 Created The device was successfully created. None
400 Bad Request Malformed request body. See error for details. Error
500 Internal Server Error Internal server error. Error
Response Headers
Status Header Type Format Description
201 Location string URI for the newly created 'Device' resource.

Delete tenant specific data

Code samples

# You can also use wget
curl -X DELETE http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id} \
  -H 'Accept: */*'

DELETE http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id} HTTP/1.1
Host: mender-inventory:8080
Accept: */*


const headers = {
  'Accept':'*/*'
};

fetch('http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}',
{
  method: 'DELETE',

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => '*/*'
}

result = RestClient.delete 'http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': '*/*'
}

r = requests.delete('http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => '*/*',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('DELETE','http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_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("http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_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{"*/*"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}", data)
    req.Header = headers

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

DELETE /tenants/{tenant_id}

Removes all data belonging to a tenant

Parameters

Name In Type Required Description
tenant_id path string true ID of given tenant.

Example responses

500 Response

Responses

Status Meaning Description Schema
204 No Content Tenant data was removed successfuly. None
500 Internal Server Error Internal server error on removing the data. Error

Delete Device

Code samples

# You can also use wget
curl -X DELETE http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id} \
  -H 'Accept: */*'

DELETE http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id} HTTP/1.1
Host: mender-inventory:8080
Accept: */*


const headers = {
  'Accept':'*/*'
};

fetch('http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}',
{
  method: 'DELETE',

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => '*/*'
}

result = RestClient.delete 'http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': '*/*'
}

r = requests.delete('http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => '*/*',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('DELETE','http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_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("http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_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{"*/*"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}", data)
    req.Header = headers

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

DELETE /tenants/{tenant_id}/devices/{device_id}

Remove a device from the inventory service

Parameters

Name In Type Required Description
tenant_id path string true ID of given tenant.
device_id path string true ID of given device.

Example responses

404 Response

Responses

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

Update Status of Devices

Code samples

# You can also use wget
curl -X POST http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/status/{status} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/status/{status} HTTP/1.1
Host: mender-inventory:8080
Content-Type: application/json
Accept: application/json

const inputBody = '[
  {
    "id": "ff8f7099-d842-42f2-9d5b-46a9ad13f90a",
    "revision": 3
  },
  {
    "id": "80f3ad8f-40f2-429a-8931-b47cebbbe9b3",
    "revision": 5
  }
]';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/status/{status}',
{
  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 'http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/status/{status}',
  params: {
  }, headers: headers

p JSON.parse(result)

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

r = requests.post('http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/status/{status}', 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','http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/status/{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("http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/status/{status}");
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", "http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/status/{status}", data)
    req.Header = headers

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

POST /tenants/{tenant_id}/devices/status/{status}

Update the status of a list of devices

An API end-point that allows to bulk update the status of a list of devices.

Body parameter

[
  {
    "id": "ff8f7099-d842-42f2-9d5b-46a9ad13f90a",
    "revision": 3
  },
  {
    "id": "80f3ad8f-40f2-429a-8931-b47cebbbe9b3",
    "revision": 5
  }
]

Parameters

Name In Type Required Description
tenant_id path string true ID of given tenant.
status path string true New status to set for the specified devices.
body body DeviceUpdate true List of devices.

Example responses

400 Response

{
  "error": "missing Authorization header"
}

Responses

Status Meaning Description Schema
200 OK The operation completed successfully. None
400 Bad Request Malformed request body. See error for details. Error
409 Conflict Write conflict, the request needs to be retried. Error
500 Internal Server Error Internal server error. Error

Update Inventory for a Device

Code samples

# You can also use wget
curl -X PATCH http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/device/{device_id}/attribute/scope/{scope} \
  -H 'Content-Type: application/json'

PATCH http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/device/{device_id}/attribute/scope/{scope} HTTP/1.1
Host: mender-inventory:8080
Content-Type: application/json

const inputBody = '[
  {
    "name": "ip_addr_eth",
    "description": "Device IP address on ethernet interface",
    "value": "127.0.0.1"
  }
]';
const headers = {
  'Content-Type':'application/json'
};

fetch('http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/device/{device_id}/attribute/scope/{scope}',
{
  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'
}

result = RestClient.patch 'http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/device/{device_id}/attribute/scope/{scope}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json'
}

r = requests.patch('http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/device/{device_id}/attribute/scope/{scope}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

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

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('PATCH','http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/device/{device_id}/attribute/scope/{scope}', 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("http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/device/{device_id}/attribute/scope/{scope}");
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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PATCH", "http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/device/{device_id}/attribute/scope/{scope}", data)
    req.Header = headers

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

PATCH /tenants/{tenant_id}/device/{device_id}/attribute/scope/{scope}

Update multiple inventory attributes in a single scope for a device

An API end-point that allows to update the inventory attributes in a single scope for a device.

Body parameter

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

Parameters

Name In Type Required Description
tenant_id path string true ID of given tenant.
device_id path string true ID of given device.
scope path string true Scope of the inventory attributes.
body body Attribute true List of inventory attributes to set.

Responses

Status Meaning Description Schema
200 OK Device inventory successfully updated. None
400 Bad Request Error descriptor. None
500 Internal Server Error Error descriptor. None

Get Device Groups

Code samples

# You can also use wget
curl -X GET http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}/groups \
  -H 'Accept: */*'

GET http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}/groups HTTP/1.1
Host: mender-inventory:8080
Accept: */*


const headers = {
  'Accept':'*/*'
};

fetch('http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}/groups',
{
  method: 'GET',

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => '*/*'
}

result = RestClient.get 'http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}/groups',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': '*/*'
}

r = requests.get('http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}/groups', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => '*/*',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('GET','http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}/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("http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}/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{"*/*"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}/groups", data)
    req.Header = headers

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

GET /tenants/{tenant_id}/devices/{device_id}/groups

Get a list of groups the device belongs to

Parameters

Name In Type Required Description
tenant_id path string true ID of given tenant.
device_id path string true Device identifier.

Example responses

200 Response

Responses

Status Meaning Description Schema
200 OK Successful response. Groups
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

Check if devices belongs to given groups

Code samples

# You can also use wget
curl -X POST http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/test/devices/groups \
  -H 'Content-Type: application/json'

POST http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/test/devices/groups HTTP/1.1
Host: mender-inventory:8080
Content-Type: application/json

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

fetch('http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/test/devices/groups',
{
  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'
}

result = RestClient.post 'http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/test/devices/groups',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json'
}

r = requests.post('http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/test/devices/groups', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

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

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/test/devices/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("http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/test/devices/groups");
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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/test/devices/groups", data)
    req.Header = headers

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

POST /tenants/{tenant_id}/test/devices/groups

Check if devices belongs to given groups

An API end-point that allows to check if devices belongs to certain groups.

Body parameter

{
  "devices": [
    "string"
  ],
  "groups": [
    "string"
  ]
}

Parameters

Name In Type Required Description
tenant_id path string true ID of given tenant.
body body DevicesInGroupsReq true

Responses

Status Meaning Description Schema
200 OK All the devices belong to given groups. None
404 Not Found Error descriptor. None
500 Internal Server Error Error descriptor. None

Start Re-indexing

Code samples

# You can also use wget
curl -X POST http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}/reindex \
  -H 'Accept: */*'

POST http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}/reindex HTTP/1.1
Host: mender-inventory:8080
Accept: */*


const headers = {
  'Accept':'*/*'
};

fetch('http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}/reindex',
{
  method: 'POST',

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

require 'rest-client'
require 'json'

headers = {
  'Accept' => '*/*'
}

result = RestClient.post 'http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}/reindex',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': '*/*'
}

r = requests.post('http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}/reindex', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => '*/*',
);

$client = new \GuzzleHttp\Client();

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

try {
    $response = $client->request('POST','http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}/reindex', 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("http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}/reindex");
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{
        "Accept": []string{"*/*"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://mender-inventory:8080/api/internal/v1/inventory/tenants/{tenant_id}/devices/{device_id}/reindex", data)
    req.Header = headers

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

POST /tenants/{tenant_id}/devices/{device_id}/reindex

Start reindexing device attributes.

Parameters

Name In Type Required Description
service query string false The name of the calling service.
device_id path string true ID of the device that needs reindexing.
tenant_id path string true ID of tenant owning the device.

Example responses

400 Response

Responses

Status Meaning Description Schema
200 OK Attributes have been re-indexed. None
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal server error. Error

Schemas

Error

{
  "error": "missing Authorization header"
}

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.

TenantNew

{
  "tenant_id": "1234"
}

Tenant configuration.

Properties
Name Type Required Description
tenant_id string false ID of given tenant.

DeviceNew

{
  "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"
    }
  ]
}

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

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.

DeviceUpdate

{
  "id": "string",
  "revision": 0
}

Object containing device id and device revision of the device to update.

Properties
Name Type Required Description
id string true Device identifier.
revision number(integer) true Device object revision.

Groups

{
  "groups": [
    "test",
    "production"
  ]
}

Properties
Name Type Required Description
groups [string] true List of device's groups.

DevicesInGroupsReq

{
  "devices": [
    "string"
  ],
  "groups": [
    "string"
  ]
}

Object containing list of device IDs and list of groups.

Properties
Name Type Required Description
devices [string] true List of device IDs.
groups [string] true List of group names.

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. Not exposed via the API Gateway - intended for internal use only.

Base URLs:

Search Device Inventories

Code samples

# You can also use wget
curl -X POST http://mender-inventory:8080/api/internal/v2/inventory/tenants/{tenant_id}/filters/search \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-inventory:8080/api/internal/v2/inventory/tenants/{tenant_id}/filters/search HTTP/1.1
Host: mender-inventory:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "page": 1,
  "per_page": 20,
  "device_ids": [
    "string"
  ],
  "text": "string",
  "filters": [
    {
      "type": "$eq",
      "attribute": "serial_no",
      "scope": "inventory",
      "value": "123456789"
    }
  ],
  "sort": [
    {
      "attribute": "serial_no",
      "scope": "inventory",
      "order": "asc"
    }
  ],
  "attributes": [
    {
      "attribute": "serial_no",
      "scope": "inventory"
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-inventory:8080/api/internal/v2/inventory/tenants/{tenant_id}/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'
}

result = RestClient.post 'http://mender-inventory:8080/api/internal/v2/inventory/tenants/{tenant_id}/filters/search',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.post('http://mender-inventory:8080/api/internal/v2/inventory/tenants/{tenant_id}/filters/search', 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','http://mender-inventory:8080/api/internal/v2/inventory/tenants/{tenant_id}/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("http://mender-inventory:8080/api/internal/v2/inventory/tenants/{tenant_id}/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://mender-inventory:8080/api/internal/v2/inventory/tenants/{tenant_id}/filters/search", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /tenants/{tenant_id}/filters/search

Search device inventories based on attributes

Returns a paged collection of devices and their attributes.

It accepts optional filters and sort parameters as body parameters.

Body parameter

{
  "page": 1,
  "per_page": 20,
  "device_ids": [
    "string"
  ],
  "text": "string",
  "filters": [
    {
      "type": "$eq",
      "attribute": "serial_no",
      "scope": "inventory",
      "value": "123456789"
    }
  ],
  "sort": [
    {
      "attribute": "serial_no",
      "scope": "inventory",
      "order": "asc"
    }
  ],
  "attributes": [
    {
      "attribute": "serial_no",
      "scope": "inventory"
    }
  ]
}

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.
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 Number of results per page.
» device_ids body [string] false List of device IDs
» text body string false Free-text search query
» filters body [FilterPredicate] false List of filter predicates, chained with boolean AND operators to build the search condition definition.
»» scope body string true The scope of the attribute.
»» attribute body string true Name of the attribute to be queried for filtering.
»» 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 criterias
»» scope body string true The scope of the attribute.
»» attribute body string true Name of the attribute to be queried for filtering.
»» order body string true Order direction, ascending or descending.
» attributes body [SelectAttribute] false List of attributes to select and return
»» attribute body string true Attribute name.
»» scope body string true Attribute scope.
Detailed descriptions

»» scope: The scope of the attribute.

Scope is a string and acts as namespace for the attribute name.

»» value: 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.

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.

»» scope: The scope of the attribute.

Scope is a string and acts as namespace for the attribute name.

»» order: Order direction, ascending or descending.

Defaults to ascending.

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": "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. 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

Show Filter

Code samples

# You can also use wget
curl -X GET http://mender-inventory:8080/api/internal/v2/inventory/tenants/{tenant_id}/filters/{id} \
  -H 'Accept: application/json'

GET http://mender-inventory:8080/api/internal/v2/inventory/tenants/{tenant_id}/filters/{id} HTTP/1.1
Host: mender-inventory:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-inventory:8080/api/internal/v2/inventory/tenants/{tenant_id}/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'
}

result = RestClient.get 'http://mender-inventory:8080/api/internal/v2/inventory/tenants/{tenant_id}/filters/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-inventory:8080/api/internal/v2/inventory/tenants/{tenant_id}/filters/{id}', 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','http://mender-inventory:8080/api/internal/v2/inventory/tenants/{tenant_id}/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("http://mender-inventory:8080/api/internal/v2/inventory/tenants/{tenant_id}/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-inventory:8080/api/internal/v2/inventory/tenants/{tenant_id}/filters/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /tenants/{tenant_id}/filters/{id}

Return the definition of a saved filter

Returns the definition of a saved filter from its unique identifier.

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.
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
400 Bad Request Missing or malformed request parameters. See error for details. Error
404 Not Found The filter was not found. ErrorNotFound
500 Internal Server Error Internal error. Error

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).

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.

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

SelectAttribute

{
  "attribute": "serial_no",
  "scope": "inventory"
}

Inventory attribute

Properties
Name Type Required Description
attribute string true Attribute name.
scope string true Attribute scope.

SortCriteria

{
  "attribute": "serial_no",
  "scope": "inventory",
  "order": "asc"
}

Sort criteria definition

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.
order string true Order direction, ascending or descending.

Defaults to ascending.
Enumerated Values
Property Value
order asc
order desc

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]

IoT Manager

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

Internal API for managing IoT Cloud integrations.

Base URLs:

Check Health

Code samples

# You can also use wget
curl -X GET http://mender-iot-manager:8080/api/internal/v1/iot-manager/health \
  -H 'Accept: application/json'

GET http://mender-iot-manager:8080/api/internal/v1/iot-manager/health HTTP/1.1
Host: mender-iot-manager:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-iot-manager:8080/api/internal/v1/iot-manager/health',
{
  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 'http://mender-iot-manager:8080/api/internal/v1/iot-manager/health',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-iot-manager:8080/api/internal/v1/iot-manager/health', 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','http://mender-iot-manager:8080/api/internal/v1/iot-manager/health', 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("http://mender-iot-manager:8080/api/internal/v1/iot-manager/health");
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", "http://mender-iot-manager:8080/api/internal/v1/iot-manager/health", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /health

Get health status of service

Example responses

400 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content Service is healthy. None
400 Bad Request Invalid Request. Error
500 Internal Server Error Internal Server Error. Error

Check Liveliness

Code samples

# You can also use wget
curl -X GET http://mender-iot-manager:8080/api/internal/v1/iot-manager/alive \
  -H 'Accept: application/json'

GET http://mender-iot-manager:8080/api/internal/v1/iot-manager/alive HTTP/1.1
Host: mender-iot-manager:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-iot-manager:8080/api/internal/v1/iot-manager/alive',
{
  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 'http://mender-iot-manager:8080/api/internal/v1/iot-manager/alive',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-iot-manager:8080/api/internal/v1/iot-manager/alive', 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','http://mender-iot-manager:8080/api/internal/v1/iot-manager/alive', 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("http://mender-iot-manager:8080/api/internal/v1/iot-manager/alive");
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", "http://mender-iot-manager:8080/api/internal/v1/iot-manager/alive", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /alive

Get service liveliness status.

Example responses

500 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content Service is up and serving requests. None
500 Internal Server Error Internal Server Error. Error

Provision device

Code samples

# You can also use wget
curl -X POST http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/devices \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/devices HTTP/1.1
Host: mender-iot-manager:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "status": "accepted",
  "auth_sets": [
    {
      "id": "string",
      "device_id": "string",
      "identity_data": {},
      "pubkey": "string",
      "status": "string",
      "ts": "2019-08-24T14:15:22Z"
    }
  ],
  "created_ts": "2019-08-24T14:15:22Z"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/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'
}

result = RestClient.post 'http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/devices',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.post('http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/devices', 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','http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/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("http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/devices", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /tenants/{tenantId}/devices

Register a new device with the deviceconfig service.

Body parameter

{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "status": "accepted",
  "auth_sets": [
    {
      "id": "string",
      "device_id": "string",
      "identity_data": {},
      "pubkey": "string",
      "status": "string",
      "ts": "2019-08-24T14:15:22Z"
    }
  ],
  "created_ts": "2019-08-24T14:15:22Z"
}

Parameters

Name In Type Required Description
tenantId path string true ID of tenant the device belongs to.
body body NewDevice true

Example responses

400 Response

{
  "error": "bad request parameters",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

409 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
202 Accepted The device provisioning event was accepted and will be processed asynchronously. None
400 Bad Request Invalid Request. Error
409 Conflict A device with the same ID already exists in Iot Hub. Error
500 Internal Server Error Internal Server Error. Error

Delete tenant

Code samples

# You can also use wget
curl -X DELETE http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId} \
  -H 'Accept: application/json'

DELETE http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId} HTTP/1.1
Host: mender-iot-manager:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}',
{
  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'
}

result = RestClient.delete 'http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.delete('http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}', 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('DELETE','http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}', 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("http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}");
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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /tenants/{tenantId}

Delete all data belonging to a given tenant.

Parameters

Name In Type Required Description
tenantId path string true ID of tenant to remove.

Example responses

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content The removal of tenant data was successful. None
500 Internal Server Error Internal Server Error. Error

Decommission device

Code samples

# You can also use wget
curl -X DELETE http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/devices/{deviceId} \
  -H 'Accept: application/json'

DELETE http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/devices/{deviceId} HTTP/1.1
Host: mender-iot-manager:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/devices/{deviceId}',
{
  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'
}

result = RestClient.delete 'http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/devices/{deviceId}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.delete('http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/devices/{deviceId}', 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('DELETE','http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/devices/{deviceId}', 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("http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/devices/{deviceId}");
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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/devices/{deviceId}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /tenants/{tenantId}/devices/{deviceId}

Remove a device from Iot Hub.

Parameters

Name In Type Required Description
tenantId path string true ID of tenant the device belongs to.
deviceId path string true ID of the target device.

Example responses

500 Response

{
  "error": "internal error",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
202 Accepted The device decomissioning event was accepted and will be processed asynchronously. None
500 Internal Server Error Internal Server Error. Error

Update device statuses

Code samples

# You can also use wget
curl -X PUT http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/bulk/devices/status/{status} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

PUT http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/bulk/devices/status/{status} HTTP/1.1
Host: mender-iot-manager:8080
Content-Type: application/json
Accept: application/json

const inputBody = '[
  {
    "id": "string"
  }
]';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/bulk/devices/status/{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'
}

result = RestClient.put 'http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/bulk/devices/status/{status}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.put('http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/bulk/devices/status/{status}', 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','http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/bulk/devices/status/{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("http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/bulk/devices/status/{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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "http://mender-iot-manager:8080/api/internal/v1/iot-manager/tenants/{tenantId}/bulk/devices/status/{status}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PUT /tenants/{tenantId}/bulk/devices/status/{status}

Update device statuses in bulk.

Body parameter

[
  {
    "id": "string"
  }
]

Parameters

Name In Type Required Description
tenantId path string true ID of tenant the device belongs to.
status path string true The status of the device
body body array[object] true
Enumerated Values
Parameter Value
status accepted
status noauth
status pending
status preauthorized
status rejected

Example responses

400 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
202 Accepted The device status update bulk event was accepted and will be processed asynchronously. None
400 Bad Request Bad Request. Error
500 Internal Server Error Internal Server Error. Error

Schemas

Error

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.
request_id string false Request ID passed with the request X-MEN-RequestID header or generated by the server.

NewDevice

{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "status": "accepted",
  "auth_sets": [
    {
      "id": "string",
      "device_id": "string",
      "identity_data": {},
      "pubkey": "string",
      "status": "string",
      "ts": "2019-08-24T14:15:22Z"
    }
  ],
  "created_ts": "2019-08-24T14:15:22Z"
}

Properties
Name Type Required Description
id string(uuid) true ID of the new device.
status string false Authorization status for the device.
auth_sets [AuthSet] false [AuthSet describes the identity a device uses to authenticate with the Mender servier.]
created_ts string(date-time) false The creation timestamp of the device.
Enumerated Values
Property Value
status accepted
status noauth
status pending
status preauthorized
status rejected

AuthSet

{
  "id": "string",
  "device_id": "string",
  "identity_data": {},
  "pubkey": "string",
  "status": "string",
  "ts": "2019-08-24T14:15:22Z"
}

AuthSet describes the identity a device uses to authenticate with the Mender servier.

Properties
Name Type Required Description
id string false The unique ID of the authentication set.
device_id string false The unique ID of the device the authentication set belongs.
identity_data object false The device's identity data.
pubkey string false PEM-encoded public key of the device authentication set.
status string false Authorization status of the set.
ts string(date-time) false The creation timestamp of the authentication set.

Mender Gateway

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

Internal API for the Mender Gateway

Base URLs:

Check Liveliness

Code samples

# You can also use wget
curl -X GET http://mender-gateway/api/internal/v1/gateway/alive \
  -H 'Accept: application/json'

GET http://mender-gateway/api/internal/v1/gateway/alive HTTP/1.1
Host: mender-gateway
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-gateway/api/internal/v1/gateway/alive',
{
  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 'http://mender-gateway/api/internal/v1/gateway/alive',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-gateway/api/internal/v1/gateway/alive', 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','http://mender-gateway/api/internal/v1/gateway/alive', 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("http://mender-gateway/api/internal/v1/gateway/alive");
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", "http://mender-gateway/api/internal/v1/gateway/alive", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /alive

Get service liveliness status.

Example responses

500 Response

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Responses

Status Meaning Description Schema
204 No Content Service is up and serving requests. None
500 Internal Server Error Internal Server Error. Error

Schemas

Error

{
  "error": "<error description>",
  "request_id": "eed14d55-d996-42cd-8248-e806663810a8"
}

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.
request_id string false Request ID passed with the request X-MEN-RequestID header or generated by the server.

Tenant administration

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 tenant administration, not exposed via the API Gateway - intended for internal use only.

Base URLs:

Check Health

Code samples

# You can also use wget
curl -X GET http://mender-tenantadm:8080/api/internal/v1/tenantadm/health \
  -H 'Accept: application/json'

GET http://mender-tenantadm:8080/api/internal/v1/tenantadm/health HTTP/1.1
Host: mender-tenantadm:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-tenantadm:8080/api/internal/v1/tenantadm/health',
{
  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 'http://mender-tenantadm:8080/api/internal/v1/tenantadm/health',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-tenantadm:8080/api/internal/v1/tenantadm/health', 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','http://mender-tenantadm:8080/api/internal/v1/tenantadm/health', 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("http://mender-tenantadm:8080/api/internal/v1/tenantadm/health");
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", "http://mender-tenantadm:8080/api/internal/v1/tenantadm/health", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /health

Check the health of the service

Example responses

500 Response

{
  "error": "tenant_token is invalid"
}

Responses

Status Meaning Description Schema
204 No Content Service is healthy and all dependencies are up and running. None
500 Internal Server Error Unexpected internal error Error
503 Service Unavailable Service unhealthy / not ready to accept traffic. At least one dependency is not running. Error

Check Liveliness

Code samples

# You can also use wget
curl -X GET http://mender-tenantadm:8080/api/internal/v1/tenantadm/alive \
  -H 'Accept: application/json'

GET http://mender-tenantadm:8080/api/internal/v1/tenantadm/alive HTTP/1.1
Host: mender-tenantadm:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-tenantadm:8080/api/internal/v1/tenantadm/alive',
{
  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 'http://mender-tenantadm:8080/api/internal/v1/tenantadm/alive',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-tenantadm:8080/api/internal/v1/tenantadm/alive', 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','http://mender-tenantadm:8080/api/internal/v1/tenantadm/alive', 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("http://mender-tenantadm:8080/api/internal/v1/tenantadm/alive");
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", "http://mender-tenantadm:8080/api/internal/v1/tenantadm/alive", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /alive

*Trivial endpoint that unconditionally returns an empty 200 response whenever the API handler is running correctly. *

Example responses

500 Response

{
  "error": "tenant_token is invalid"
}

Responses

Status Meaning Description Schema
204 No Content Service is up and running None
500 Internal Server Error Internal API error Error

Verify Tenant Token

Code samples

# You can also use wget
curl -X POST http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/verify \
  -H 'Accept: application/json' \
  -H 'Authorization: string'

POST http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/verify HTTP/1.1
Host: mender-tenantadm:8080
Accept: application/json
Authorization: string


const headers = {
  'Accept':'application/json',
  'Authorization':'string'
};

fetch('http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/verify',
{
  method: 'POST',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'string'
}

result = RestClient.post 'http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/verify',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'string'
}

r = requests.post('http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/verify', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'string',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/verify', 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("http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/verify");
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{
        "Accept": []string{"application/json"},
        "Authorization": []string{"string"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/verify", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /tenants/verify

Check the validity of a tenant token

Verifies the Tenant Token and returns the associated Tenant.

Parameters

Name In Type Required Description
Authorization header string(Bearer [token]) true The tenant token in base64-encoded form.

Example responses

The token is valid. A tenant descriptor is returned.

{
  "id": "507f191e810c19729de860ea",
  "name": "Acme"
}

500 Response

{
  "error": "tenant_token is invalid"
}

Responses

Status Meaning Description Schema
200 OK The token is valid. A tenant descriptor is returned. Tenant
401 Unauthorized Verification failed. None
500 Internal Server Error Unexpected error. Error

List Tenants

Code samples

# You can also use wget
curl -X GET http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants \
  -H 'Accept: application/json'

GET http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants HTTP/1.1
Host: mender-tenantadm:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants',
{
  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 'http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants', 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','http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants', 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("http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants");
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", "http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /tenants

List known tenants

Returns a paged collection of existing tenants.

Parameters

Name In Type Required Description
id query string false Tenant ID filter. Matches if the tenant ID is equal to this string.
q query string false Tenant filter. Matches if the tenant ID is equal to this string, or tenant's name or tenant's admin username contain this string.
page query number(integer) false Starting page.
per_page query number(integer) false Maximum number of results per page.
Detailed descriptions

id: Tenant ID filter. Matches if the tenant ID is equal to this string.

q: Tenant filter. Matches if the tenant ID is equal to this string, or tenant's name or tenant's admin username contain this string.

Example responses

Successful response.

[
  {
    "id": "507f191e810c19729de860ea",
    "name": "Acme",
    "plan": "os"
  },
  {
    "id": "507f1f77bcf86cd799439011",
    "name": "Foo Inc.",
    "plan": "professional"
  }
]

400 Response

{
  "error": "tenant_token is invalid"
}

Responses

Status Meaning Description Schema
200 OK Successful response. Inline
400 Bad Request Invalid parameters. See error message for details. Error
500 Internal Server Error Internal server error. Error
Response Schema

Status Code 200

ListOfTenants

Name Type Required Restrictions Description
ListOfTenants [Tenant] false [Tenant descriptor.]
» id string false Autogenerated tenant ID.
» name string false Name of the tenant's organization.
» tenant_token string false Currently used tenant token.
» status string false Status of the tenant account.
» plan string false Plan assigned to the tenant account.
» additional_info TenantAdditionalInfo false Additional information about a tenant.
»» marketing boolean false Marketing
»» campaign string false Campaign
» api_limits TenantApiLimits false API usage quota and burst limit definitions for a tenant - per API type.
»» management ApiLimits false Usage quota and burst limit definitions for an API type.
»»» bursts [ApiBurst] false Collection of api burst limit definitions over specified API resources.
»»»» action string false HTTP verb.
»»»» uri string false URI of the resource subject to the limit.
»»»» min_interval_sec integer false Minimum allowed interval, in seconds, between subsequent calls to 'action' on 'uri' (10 = one call every 10 seconds, etc.)
»»» quota ApiQuota false API usage quota definition.
»»»» max_calls integer false Maximum allowed number of calls within 'interval'. A value of 0 means 'no limit'.
»»»» interval_sec integer false Interval definition, in seconds (60 = 1 minute, 3600 = 1 hour, etc.).
»» devices ApiLimits false Usage quota and burst limit definitions for an API type.
Enumerated Values
Property Value
status active
status suspended
plan os
plan enterprise
plan professional
plan
Response Headers
Status Header Type Format Description
200 Link string Standard header, used for page navigation.

Supported relation types are 'first', 'next' and 'prev'. |

Show Tenant

Code samples

# You can also use wget
curl -X GET http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_id} \
  -H 'Accept: application/json'

GET http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_id} HTTP/1.1
Host: mender-tenantadm:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_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'
}

result = RestClient.get 'http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_id}', 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','http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_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("http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /tenants/{tenant_id}

Obtain information about selected tenant

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.

Example responses

200 Response

{
  "id": "507f191e810c19729de860ea",
  "name": "Acme",
  "tenant_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODcwNTU3MzUsImp0aSI6IjM5MTJiZDNmLWVjMTEtNDgwNy05MmE4LTBkOTVjMWFmYjU1NCIsImlzcyI6Ik1lbmRlciIsInN1YiI6ImQ0NTljOTFmZDkzMWFkOGM0ZDk4ZGIyZjdlZjU3NjYxNDI3NDJiZDMyMzM0ZjIyNjYyZTNiNjE5YmRiZTJhNTYifQ.iY2XuyuDOHW9ilPPeeHuwmz9A-6asDqdfy3mCjXuODns1SshbuH_XXFPa7s2PpXCMkhEHB82nLEjwcSO7gTIz1uqzjyGufVbXlOiZqPrCXUm4DKvhSgANiVKfkw_JvD1w-V0jyctBcrUifIhqhRlhXNAJh3c5XAMzxe2kwt9t3JW5bXiXroc64gXdv0gnX-o7YgdrFfau3rAaMFinKqHzACmeE5YhEVF9eQPJQ99U0PO6tVCcG39O-vtt51ClWh3BVeeQrHcr5eWQZWFMHThdeoRitLwvsN8wzrEKUoL9q9SlFnu4uGJkfOfTuiafgF1pJ-UBDYdBdV4sV9626PdHQ",
  "status": "active",
  "plan": "os",
  "api_limits": {
    "management": {
      "quota": {
        "max_calls": 100,
        "interval_sec": 60
      }
    },
    "devices": {
      "quota": {
        "max_calls": 1000,
        "interval_sec": 60
      },
      "bursts": [
        {
          "action": "PATCH",
          "uri": "/api/devices/v1/inventory/device/attributes",
          "min_interval_sec": 10
        },
        {
          "action": "POST",
          "uri": "/api/devices/v1/deployments/device/deployments/next",
          "min_interval_sec": 60
        }
      ]
    }
  }
}

Responses

Status Meaning Description Schema
200 OK A tenant descriptor is returned. Tenant
404 Not Found Tenant not found. Error
500 Internal Server Error Unexpected error. Error

Delete Tenant

Code samples

# You can also use wget
curl -X DELETE http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_id} \
  -H 'Accept: application/json'

DELETE http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_id} HTTP/1.1
Host: mender-tenantadm:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_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'
}

result = RestClient.delete 'http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.delete('http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_id}', 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('DELETE','http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_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("http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /tenants/{tenant_id}

Delete all the information belonging to a tenant

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.

Example responses

204 Response

{
  "id": "507f191e810c19729de860ea",
  "name": "Acme",
  "tenant_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODcwNTU3MzUsImp0aSI6IjM5MTJiZDNmLWVjMTEtNDgwNy05MmE4LTBkOTVjMWFmYjU1NCIsImlzcyI6Ik1lbmRlciIsInN1YiI6ImQ0NTljOTFmZDkzMWFkOGM0ZDk4ZGIyZjdlZjU3NjYxNDI3NDJiZDMyMzM0ZjIyNjYyZTNiNjE5YmRiZTJhNTYifQ.iY2XuyuDOHW9ilPPeeHuwmz9A-6asDqdfy3mCjXuODns1SshbuH_XXFPa7s2PpXCMkhEHB82nLEjwcSO7gTIz1uqzjyGufVbXlOiZqPrCXUm4DKvhSgANiVKfkw_JvD1w-V0jyctBcrUifIhqhRlhXNAJh3c5XAMzxe2kwt9t3JW5bXiXroc64gXdv0gnX-o7YgdrFfau3rAaMFinKqHzACmeE5YhEVF9eQPJQ99U0PO6tVCcG39O-vtt51ClWh3BVeeQrHcr5eWQZWFMHThdeoRitLwvsN8wzrEKUoL9q9SlFnu4uGJkfOfTuiafgF1pJ-UBDYdBdV4sV9626PdHQ",
  "status": "active",
  "plan": "os",
  "api_limits": {
    "management": {
      "quota": {
        "max_calls": 100,
        "interval_sec": 60
      }
    },
    "devices": {
      "quota": {
        "max_calls": 1000,
        "interval_sec": 60
      },
      "bursts": [
        {
          "action": "PATCH",
          "uri": "/api/devices/v1/inventory/device/attributes",
          "min_interval_sec": 10
        },
        {
          "action": "POST",
          "uri": "/api/devices/v1/deployments/device/deployments/next",
          "min_interval_sec": 60
        }
      ]
    }
  }
}

Responses

Status Meaning Description Schema
204 No Content All the tenant data removed. Tenant
500 Internal Server Error Internal error on removal. Error

Update Tenant

Code samples

# You can also use wget
curl -X PUT http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

PUT http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_id} HTTP/1.1
Host: mender-tenantadm:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "name": "Acme",
  "plan": "os",
  "trial": true,
  "trial_expiration": "2021-01-01T00:00:00Z",
  "suspend_at": "2021-01-01T00:00:00Z",
  "api_limits": {
    "management": {
      "quota": {
        "max_calls": 100,
        "interval_sec": 60
      }
    },
    "devices": {
      "quota": {
        "max_calls": 1000,
        "interval_sec": 60
      },
      "bursts": [
        {
          "action": "PATCH",
          "uri": "/api/devices/v1/inventory/device/attributes",
          "min_interval_sec": 10
        },
        {
          "action": "POST",
          "uri": "/api/devices/v1/deployments/device/deployments/next",
          "min_interval_sec": 60
        }
      ]
    }
  }
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_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'
}

result = RestClient.put 'http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.put('http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_id}', 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','http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_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("http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{tenant_id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PUT /tenants/{tenant_id}

Update tenant information

Update tenant information.

Body parameter

{
  "name": "Acme",
  "plan": "os",
  "trial": true,
  "trial_expiration": "2021-01-01T00:00:00Z",
  "suspend_at": "2021-01-01T00:00:00Z",
  "api_limits": {
    "management": {
      "quota": {
        "max_calls": 100,
        "interval_sec": 60
      }
    },
    "devices": {
      "quota": {
        "max_calls": 1000,
        "interval_sec": 60
      },
      "bursts": [
        {
          "action": "PATCH",
          "uri": "/api/devices/v1/inventory/device/attributes",
          "min_interval_sec": 10
        },
        {
          "action": "POST",
          "uri": "/api/devices/v1/deployments/device/deployments/next",
          "min_interval_sec": 60
        }
      ]
    }
  }
}

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.
body body TenantUpdate true Updated tenant data.

Example responses

400 Response

{
  "error": "tenant_token is invalid"
}

Responses

Status Meaning Description Schema
204 No Content Tenant information updated. None
400 Bad Request The request body is malformed. Error
404 Not Found The tenant does not exist. Error
500 Internal Server Error Internal server error. Error

Set Account Status

Code samples

# You can also use wget
curl -X PUT http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{id}/status \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

PUT http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{id}/status HTTP/1.1
Host: mender-tenantadm:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "status": "suspended"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{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'
}

result = RestClient.put 'http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{id}/status',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.put('http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{id}/status', 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','http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{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("http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "http://mender-tenantadm:8080/api/internal/v1/tenantadm/tenants/{id}/status", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PUT /tenants/{id}/status

Suspend/unsuspend tenant's account.

Changes the given tenant's suspension status. Valid statuses are:

Body parameter

{
  "status": "suspended"
}

Parameters

Name In Type Required Description
id path string true Tenant ID.
body body Status true Target suspension status

Example responses

400 Response

{
  "error": "tenant_token is invalid"
}

Responses

Status Meaning Description Schema
200 OK The tenant was successfully (un)suspended. None
400 Bad Request The request body is malformed. See error for details. Error
404 Not Found The tenant was not found. Error
500 Internal Server Error Internal server error. Error

Schemas

Tenant

{
  "id": "507f191e810c19729de860ea",
  "name": "Acme",
  "tenant_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODcwNTU3MzUsImp0aSI6IjM5MTJiZDNmLWVjMTEtNDgwNy05MmE4LTBkOTVjMWFmYjU1NCIsImlzcyI6Ik1lbmRlciIsInN1YiI6ImQ0NTljOTFmZDkzMWFkOGM0ZDk4ZGIyZjdlZjU3NjYxNDI3NDJiZDMyMzM0ZjIyNjYyZTNiNjE5YmRiZTJhNTYifQ.iY2XuyuDOHW9ilPPeeHuwmz9A-6asDqdfy3mCjXuODns1SshbuH_XXFPa7s2PpXCMkhEHB82nLEjwcSO7gTIz1uqzjyGufVbXlOiZqPrCXUm4DKvhSgANiVKfkw_JvD1w-V0jyctBcrUifIhqhRlhXNAJh3c5XAMzxe2kwt9t3JW5bXiXroc64gXdv0gnX-o7YgdrFfau3rAaMFinKqHzACmeE5YhEVF9eQPJQ99U0PO6tVCcG39O-vtt51ClWh3BVeeQrHcr5eWQZWFMHThdeoRitLwvsN8wzrEKUoL9q9SlFnu4uGJkfOfTuiafgF1pJ-UBDYdBdV4sV9626PdHQ",
  "status": "active",
  "plan": "os",
  "api_limits": {
    "management": {
      "quota": {
        "max_calls": 100,
        "interval_sec": 60
      }
    },
    "devices": {
      "quota": {
        "max_calls": 1000,
        "interval_sec": 60
      },
      "bursts": [
        {
          "action": "PATCH",
          "uri": "/api/devices/v1/inventory/device/attributes",
          "min_interval_sec": 10
        },
        {
          "action": "POST",
          "uri": "/api/devices/v1/deployments/device/deployments/next",
          "min_interval_sec": 60
        }
      ]
    }
  }
}

Tenant descriptor.

Properties
Name Type Required Description
id string false Autogenerated tenant ID.
name string false Name of the tenant's organization.
tenant_token string false Currently used tenant token.
status string false Status of the tenant account.
plan string false Plan assigned to the tenant account.
additional_info TenantAdditionalInfo false Additional information about a tenant.
api_limits TenantApiLimits false API usage quota and burst limit definitions for a tenant - per API type.
Enumerated Values
Property Value
status active
status suspended
plan os
plan enterprise
plan professional
plan

User

{
  "name": "user@acme.com",
  "id": "8c1a4f58-7919-4c42-a656-10da91c41fe9",
  "tenant_id": "754bf88b-d1e4-402e-a9e5-b076ca7791cc"
}

User descriptor.

Properties
Name Type Required Description
name string true User name (email).
id string true User ID.
tenant_id string true Tenant ID.
plan string false User payment plan.
login object false

UserNew

{
  "name": "user@acme.com",
  "id": "8c1a4f58-7919-4c42-a656-10da91c41fe9",
  "tenant_id": "754bf88b-d1e4-402e-a9e5-b076ca7791cc"
}

New user descriptor.

Properties
Name Type Required Description
name string true A unique user name.
id string true User ID.
tenant_id string true Tenant ID.
login object false

UserUpdate

{
  "name": "new_email@acme.com"
}

Update user information.

Properties
Name Type Required Description
name string true A unique user name.

TenantUpdate

{
  "name": "Acme",
  "plan": "os",
  "trial": true,
  "trial_expiration": "2021-01-01T00:00:00Z",
  "suspend_at": "2021-01-01T00:00:00Z",
  "api_limits": {
    "management": {
      "quota": {
        "max_calls": 100,
        "interval_sec": 60
      }
    },
    "devices": {
      "quota": {
        "max_calls": 1000,
        "interval_sec": 60
      },
      "bursts": [
        {
          "action": "PATCH",
          "uri": "/api/devices/v1/inventory/device/attributes",
          "min_interval_sec": 10
        },
        {
          "action": "POST",
          "uri": "/api/devices/v1/deployments/device/deployments/next",
          "min_interval_sec": 60
        }
      ]
    }
  }
}

Update tenant information.

Properties
Name Type Required Description
name string false Name of the tenant's organization.
plan string false Plan assigned to the tenant account.
addons [Addon] false Addons configuration.
api_limits TenantApiLimits false API usage quota and burst limit definitions for a tenant - per API type.
trial boolean false True if the tenant is in trial period.
trial_expiration string false End date and time of the trial period, in ISO8601 format.
suspend_at string false Planned suspention date and time, in ISO8601 format.
Enumerated Values
Property Value
plan os
plan enterprise
plan professional
plan

Status

{
  "status": "suspended"
}

Suspension status of a tenant account.

Properties
Name Type Required Description
status string true
Enumerated Values
Property Value
status active
status suspended

ApiBurst

{
  "action": "PATCH",
  "uri": "/api/devices/v1/inventory/device/attributes",
  "min_interval_sec": 10
}

API burst limit definition.

Properties
Name Type Required Description
action string false HTTP verb.
uri string false URI of the resource subject to the limit.
min_interval_sec integer false Minimum allowed interval, in seconds, between subsequent calls to 'action' on 'uri' (10 = one call every 10 seconds, etc.)

ApiQuota

{
  "max_calls": 100,
  "interval_sec": 3600
}

API usage quota definition.

Properties
Name Type Required Description
max_calls integer false Maximum allowed number of calls within 'interval'. A value of 0 means 'no limit'.
interval_sec integer false Interval definition, in seconds (60 = 1 minute, 3600 = 1 hour, etc.).

ApiLimits

{
  "bursts": [
    {
      "action": "PATCH",
      "uri": "/api/devices/v1/inventory/device/attributes",
      "min_interval_sec": 10
    },
    {
      "action": "POST",
      "uri": "/api/devices/v1/deployments/device/deployments/next",
      "min_interval_sec": 60
    }
  ],
  "quota": {
    "max_calls": 100,
    "interval_sec": 60
  }
}

Usage quota and burst limit definitions for an API type.

Properties
Name Type Required Description
bursts [ApiBurst] false Collection of api burst limit definitions over specified API resources.
quota ApiQuota false API usage quota definition.

TenantAdditionalInfo

{
  "marketing": true,
  "campaign": "Campaign"
}

Additional information about a tenant.

Properties
Name Type Required Description
marketing boolean false Marketing
campaign string false Campaign

TenantApiLimits

{
  "management": {
    "quota": {
      "max_calls": 100,
      "interval_sec": 60
    }
  },
  "devices": {
    "quota": {
      "max_calls": 1000,
      "interval_sec": 60
    },
    "bursts": [
      {
        "action": "PATCH",
        "uri": "/api/devices/v1/inventory/device/attributes",
        "min_interval_sec": 10
      },
      {
        "action": "POST",
        "uri": "/api/devices/v1/deployments/device/deployments/next",
        "min_interval_sec": 60
      }
    ]
  }
}

API usage quota and burst limit definitions for a tenant - per API type.

Properties
Name Type Required Description
management ApiLimits false Usage quota and burst limit definitions for an API type.
devices ApiLimits false Usage quota and burst limit definitions for an API type.

Addon

{
  "name": "troubleshoot",
  "enabled": true
}

Mender addon definition.

Properties
Name Type Required Description
name string false Name of the addon (one of ['configure', 'troubleshoot']).
enabled boolean false Enabled/disabled flag.

Error

{
  "error": "tenant_token is invalid"
}

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.

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. Not exposed via the API Gateway - intended for internal use only.

Base URLs:

Check Health

Code samples

# You can also use wget
curl -X GET http://mender-useradm:8080/api/internal/v1/useradm/health \
  -H 'Accept: application/json'

GET http://mender-useradm:8080/api/internal/v1/useradm/health HTTP/1.1
Host: mender-useradm:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-useradm:8080/api/internal/v1/useradm/health',
{
  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 'http://mender-useradm:8080/api/internal/v1/useradm/health',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-useradm:8080/api/internal/v1/useradm/health', 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','http://mender-useradm:8080/api/internal/v1/useradm/health', 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("http://mender-useradm:8080/api/internal/v1/useradm/health");
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", "http://mender-useradm:8080/api/internal/v1/useradm/health", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /health

Check the health of the service

Example responses

Unexpected internal error

{
  "error": "internal error",
  "request_id": "ffd712be-d697-4cb7-814b-88ff1e2eb5f6"
}

Service unhealthy / not ready to accept traffic. At least one dependency is not running.

{
  "error": "error reaching MongoDB: context deadline exceeded",
  "request_id": "ffd712be-d697-4cb7-814b-88ff1e2eb5f6"
}

Responses

Status Meaning Description Schema
204 No Content Service is healthy and all dependencies are up and running. None
500 Internal Server Error Unexpected internal error Error
503 Service Unavailable Service unhealthy / not ready to accept traffic. At least one dependency is not running. Error

Check Liveliness

Code samples

# You can also use wget
curl -X GET http://mender-useradm:8080/api/internal/v1/useradm/alive \
  -H 'Accept: application/json'

GET http://mender-useradm:8080/api/internal/v1/useradm/alive HTTP/1.1
Host: mender-useradm:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-useradm:8080/api/internal/v1/useradm/alive',
{
  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 'http://mender-useradm:8080/api/internal/v1/useradm/alive',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-useradm:8080/api/internal/v1/useradm/alive', 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','http://mender-useradm:8080/api/internal/v1/useradm/alive', 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("http://mender-useradm:8080/api/internal/v1/useradm/alive");
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", "http://mender-useradm:8080/api/internal/v1/useradm/alive", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /alive

*Trivial endpoint that unconditionally returns an empty 200 response whenever the API handler is running correctly. *

Example responses

500 Response

{
  "error": "missing Authorization header"
}

Responses

Status Meaning Description Schema
204 No Content Service is up and running. None
500 Internal Server Error Internal API error Error

Verify JWT

Code samples

# You can also use wget
curl -X POST http://mender-useradm:8080/api/internal/v1/useradm/auth/verify \
  -H 'Accept: application/json' \
  -H 'Authorization: string' \
  -H 'X-Forwarded-Uri: string' \
  -H 'X-Forwarded-Method: GET'

POST http://mender-useradm:8080/api/internal/v1/useradm/auth/verify HTTP/1.1
Host: mender-useradm:8080
Accept: application/json
Authorization: string
X-Forwarded-Uri: string
X-Forwarded-Method: GET


const headers = {
  'Accept':'application/json',
  'Authorization':'string',
  'X-Forwarded-Uri':'string',
  'X-Forwarded-Method':'GET'
};

fetch('http://mender-useradm:8080/api/internal/v1/useradm/auth/verify',
{
  method: 'POST',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'string',
  'X-Forwarded-Uri' => 'string',
  'X-Forwarded-Method' => 'GET'
}

result = RestClient.post 'http://mender-useradm:8080/api/internal/v1/useradm/auth/verify',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'string',
  'X-Forwarded-Uri': 'string',
  'X-Forwarded-Method': 'GET'
}

r = requests.post('http://mender-useradm:8080/api/internal/v1/useradm/auth/verify', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'string',
    'X-Forwarded-Uri' => 'string',
    'X-Forwarded-Method' => 'GET',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','http://mender-useradm:8080/api/internal/v1/useradm/auth/verify', 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("http://mender-useradm:8080/api/internal/v1/useradm/auth/verify");
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{
        "Accept": []string{"application/json"},
        "Authorization": []string{"string"},
        "X-Forwarded-Uri": []string{"string"},
        "X-Forwarded-Method": []string{"GET"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://mender-useradm:8080/api/internal/v1/useradm/auth/verify", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /auth/verify

Check the validity of a token

Besides the basic validity check, checks the token expiration time and user-initiated token revocation.

Services which intend to use it should be correctly set up in the gateway's configuration.

Parameters

Name In Type Required Description
Authorization header string(Bearer [token]) true The token in base64-encoded form.
X-Forwarded-Uri header string(HTTP path) true URI the original request was sent to, the URI is expected to have
X-Forwarded-Method header string true HTTP method used when accessing the original URI
Detailed descriptions

X-Forwarded-Uri: URI the original request was sent to, the URI is expected to have at least 4 components, eg. /api/management/1.0/foo/bar

Enumerated Values
Parameter Value
X-Forwarded-Method GET
X-Forwarded-Method PUT
X-Forwarded-Method POST
X-Forwarded-Method DELETE

Example responses

400 Response

{
  "error": "missing Authorization header"
}

Responses

Status Meaning Description Schema
200 OK The token is valid. None
400 Bad Request Missing or malformed request parameters. Error
401 Unauthorized Verification failed, authentication should not be granted. Error
403 Forbidden Token has expired - apply for a new one. Error
500 Internal Server Error Unexpected error. Error

List All Users

Code samples

# You can also use wget
curl -X GET http://mender-useradm:8080/api/internal/v1/useradm/users \
  -H 'Accept: application/json'

GET http://mender-useradm:8080/api/internal/v1/useradm/users HTTP/1.1
Host: mender-useradm:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-useradm:8080/api/internal/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'
}

result = RestClient.get 'http://mender-useradm:8080/api/internal/v1/useradm/users',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-useradm:8080/api/internal/v1/useradm/users', 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','http://mender-useradm:8080/api/internal/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("http://mender-useradm:8080/api/internal/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-useradm:8080/api/internal/v1/useradm/users", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /users

*List users matching the filtering conditions. *

Parameters

Name In Type Required Description
page query number(integer) false Results page number
per_page query number(integer) false Maximum number of results per page.
id query string false Limit result by user ID, can be repeated to include multiple users in the query.
tenant_id query string false Limit result by tenant ID.
email query string false Limit result by user email, can be repeated to include multiple users in the query.
sso_provider_id query string false Filter by SSO provider ID. Must be a UUID or on the form oauth2/.
sso_subject query string false Filter by SSO subject ID.
created_after query integer false Filter users created after timestamp (UNIX timestamp).
created_before query integer false Filter users created before timestamp (UNIX timestamp).
updated_after query integer false Filter users updated after timestamp (UNIX timestamp).
updated_before query integer false Filter users updated before timestamp (UNIX timestamp).
Detailed descriptions

id: Limit result by user ID, can be repeated to include multiple users in the query.

tenant_id: Limit result by tenant ID.

email: Limit result by user email, can be repeated to include multiple users in the query.

sso_provider_id: Filter by SSO provider ID. Must be a UUID or on the form oauth2/.

sso_subject: Filter by SSO subject ID.

created_after: Filter users created after timestamp (UNIX timestamp).

created_before: Filter users created before timestamp (UNIX timestamp).

updated_after: Filter users updated after timestamp (UNIX timestamp).

updated_before: Filter users updated before timestamp (UNIX timestamp).

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",
    "tenant_id": "84430f18-d464-5194-b8ef-b1a15161bb4c",
    "tenant_ids": [
      "84430f18-d464-5194-b8ef-b1a15161bb4c",
      "2c481d66-4bd0-43ad-a8b9-61503611c745"
    ]
  }
]

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 [allOf] false

allOf

Name Type Required Restrictions Description
» anonymous 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.
»» login_ts string(date-time) false Timestamp of the last successful login.
»» verified boolean false Indicates if the user's email address has been verified.
»» tfa_status string false User Two Factor Authentication status.
»» roles [string] false List of user roles.
»»» ListOfRoles string false Role name

and

Name Type Required Restrictions Description
» anonymous TenantInfo false
»» tenant_id string false Tenant identifier of a tenant, user will log in to by default.
»» tenant_ids [string] false List of tenant Ids user can login to.

Create Tenant

Code samples

# You can also use wget
curl -X POST http://mender-useradm:8080/api/internal/v1/useradm/tenants \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-useradm:8080/api/internal/v1/useradm/tenants HTTP/1.1
Host: mender-useradm:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "tenant_id": "1234"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-useradm:8080/api/internal/v1/useradm/tenants',
{
  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 'http://mender-useradm:8080/api/internal/v1/useradm/tenants',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.post('http://mender-useradm:8080/api/internal/v1/useradm/tenants', 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','http://mender-useradm:8080/api/internal/v1/useradm/tenants', 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("http://mender-useradm:8080/api/internal/v1/useradm/tenants");
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", "http://mender-useradm:8080/api/internal/v1/useradm/tenants", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /tenants

Create a tenant with provided configuration.

Body parameter

{
  "tenant_id": "1234"
}

Parameters

Name In Type Required Description
body body TenantNew true

Example responses

500 Response

{
  "error": "missing Authorization header"
}

Responses

Status Meaning Description Schema
201 Created The tenant was created successfully. None
400 Bad Request Missing or malformed request parameters. None
500 Internal Server Error Unexpected error. Error

Assign tenant SSO

Code samples

# You can also use wget
curl -X PUT http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/sso/assign \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

PUT http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/sso/assign HTTP/1.1
Host: mender-useradm:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "tenant_id": [
    "65c76fd6e15517b2f0fbfdf1"
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/sso/assign',
{
  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 'http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/sso/assign',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.put('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/sso/assign', 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','http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/sso/assign', 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("http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/sso/assign");
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", "http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/sso/assign", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PUT /tenants/{tenant_id}/sso/assign

Assigns the SSO to the tenant

Body parameter

{
  "tenant_id": [
    "65c76fd6e15517b2f0fbfdf1"
  ]
}

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID to asign the SSO to.
body body TenantId true Existing tenant ID to get the SSO configuration from.

Example responses

400 Response

{
  "error": "missing Authorization header"
}

Responses

Status Meaning Description Schema
200 OK The SSO data was successfuly assigned, however there is additional message returned (for instance in case of replacement of existing configuration). None
201 Created The SSO data was successfuly assigned. None
400 Bad Request The request is malformed. Error
404 Not Found Tenant with given ID does not exist. Error
500 Internal Server Error Internal server error. Error

Delete tenant data

Code samples

# You can also use wget
curl -X DELETE http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id} \
  -H 'Accept: application/json'

DELETE http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id} HTTP/1.1
Host: mender-useradm:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_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'
}

result = RestClient.delete 'http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.delete('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}', 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('DELETE','http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_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("http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /tenants/{tenant_id}

Deletes all the tenant data

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID to delete.

Example responses

500 Response

{
  "error": "missing Authorization header"
}

Responses

Status Meaning Description Schema
204 No Content The tenant data was successfully deleted. None
500 Internal Server Error Internal server error. Error

Create User

Code samples

# You can also use wget
curl -X POST http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users HTTP/1.1
Host: mender-useradm:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "email": "user@acme.com",
  "password": "secret",
  "propagate": false,
  "magic_id": "a30a780b-b843-5344-80e3-0fd95a4f6fc3"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/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'
}

result = RestClient.post 'http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.post('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users', 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','http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/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("http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /tenants/{tenant_id}/users

Create user

Body parameter

{
  "email": "user@acme.com",
  "password": "secret",
  "propagate": false,
  "magic_id": "a30a780b-b843-5344-80e3-0fd95a4f6fc3"
}

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.
body body UserNew true New user data.

Example responses

400 Response

{
  "error": "missing Authorization header"
}

Responses

Status Meaning Description Schema
201 Created The user was successfully created. None
400 Bad Request The request body is malformed. Error
404 Not Found Tenant with given ID does not exist. Error
422 Unprocessable Entity User name or ID is duplicated, or limit on maximum number of users has been exceeded. Error
500 Internal Server Error Internal server error. Error

List Users

Code samples

# You can also use wget
curl -X GET http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users \
  -H 'Accept: application/json'

GET http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users HTTP/1.1
Host: mender-useradm:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/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'
}

result = RestClient.get 'http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users', 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','http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/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("http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /tenants/{tenant_id}/users

*List all users registered under the tenant owning the JWT. *

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.
id query string false Limit result by user ID, can be repeated to include multiple users in the query.
email query string false Limit result by user email, can be repeated to include multiple users in the query.
created_after query integer false Filter users created after timestamp (UNIX timestamp).
created_before query integer false Filter users created before timestamp (UNIX timestamp).
updated_after query integer false Filter users updated after timestamp (UNIX timestamp).
updated_before query integer false Filter users updated before timestamp (UNIX timestamp).
Detailed descriptions

id: Limit result by user ID, can be repeated to include multiple users in the query.

email: Limit result by user email, can be repeated to include multiple users in the query.

created_after: Filter users created after timestamp (UNIX timestamp).

created_before: Filter users created before timestamp (UNIX timestamp).

updated_after: Filter users updated after timestamp (UNIX timestamp).

updated_before: Filter users updated before timestamp (UNIX timestamp).

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.
» login_ts string(date-time) false Timestamp of the last successful login.
» verified boolean false Indicates if the user's email address has been verified.
» tfa_status string false User Two Factor Authentication status.
» roles [string] false List of user roles.
»» ListOfRoles string false Role name

List Users' email addresses

Code samples

# You can also use wget
curl -X GET http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/devices/{device_id}/users \
  -H 'Accept: application/json'

GET http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/devices/{device_id}/users HTTP/1.1
Host: mender-useradm:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/devices/{device_id}/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'
}

result = RestClient.get 'http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/devices/{device_id}/users',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/devices/{device_id}/users', 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','http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/devices/{device_id}/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("http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/devices/{device_id}/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/devices/{device_id}/users", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /tenants/{tenant_id}/devices/{device_id}/users

*List users' email addresses of users with access to a given device. *

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.
device_id path string true Device ID.

Example responses

200 Response

{
  "emails": [
    "demo@example.com",
    "admin@example.com"
  ]
}

Responses

Status Meaning Description Schema
200 OK Successful response. Emails
400 Bad Request Device id not provided. Error
500 Internal Server Error Internal server error. Error

Delete User

Code samples

# You can also use wget
curl -X DELETE http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users/{user_id} \
  -H 'Accept: application/json'

DELETE http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users/{user_id} HTTP/1.1
Host: mender-useradm:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users/{user_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'
}

result = RestClient.delete 'http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users/{user_id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.delete('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users/{user_id}', 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('DELETE','http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users/{user_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("http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users/{user_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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/users/{user_id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /tenants/{tenant_id}/users/{user_id}

Delete a user

Remove a user from the tenant.

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.
user_id path string true User ID.

Example responses

400 Response

{
  "error": "missing Authorization header"
}

Responses

Status Meaning Description Schema
204 No Content User deleted. None
400 Bad Request Invalid parameters. Error
500 Internal Server Error Internal server error. Error

Revoke User Tokens

Code samples

# You can also use wget
curl -X DELETE http://mender-useradm:8080/api/internal/v1/useradm/tokens?tenant_id=string \
  -H 'Accept: application/json'

DELETE http://mender-useradm:8080/api/internal/v1/useradm/tokens?tenant_id=string HTTP/1.1
Host: mender-useradm:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-useradm:8080/api/internal/v1/useradm/tokens?tenant_id=string',
{
  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'
}

result = RestClient.delete 'http://mender-useradm:8080/api/internal/v1/useradm/tokens',
  params: {
  'tenant_id' => 'string'
}, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.delete('http://mender-useradm:8080/api/internal/v1/useradm/tokens', params={
  'tenant_id': 'string'
}, 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('DELETE','http://mender-useradm:8080/api/internal/v1/useradm/tokens', 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("http://mender-useradm:8080/api/internal/v1/useradm/tokens?tenant_id=string");
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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-useradm:8080/api/internal/v1/useradm/tokens", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /tokens

Delete all user tokens

This endpoint is designed to be used for tenant account suspension purpose. When only tenant_id parameter is set, tokens for all tenant users will be removed. It is also possible to remove tokens for user with given user_id by setting optional user_id parameter.

Parameters

Name In Type Required Description
tenant_id query string true Tenant ID.
user_id query string false User ID.

Example responses

400 Response

{
  "error": "missing Authorization header"
}

Responses

Status Meaning Description Schema
204 No Content Tokens deleted. None
400 Bad Request Invalid parameters. Error
500 Internal Server Error Internal server error. Error

Get Tenant Limits

Code samples

# You can also use wget
curl -X GET http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits \
  -H 'Accept: application/json'

GET http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits HTTP/1.1
Host: mender-useradm:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits',
{
  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 'http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits', 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','http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits', 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("http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits");
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", "http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /tenants/{tenant_id}/limits

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.

Example responses

200 Response

{
  "limit": 123
}

Responses

Status Meaning Description Schema
200 OK Successful response. Limits
400 Bad Request Invalid parameters. See error message for details. Error
500 Internal Server Error Internal server error. Error

Update Tenant Limits

Code samples

# You can also use wget
curl -X PUT http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

PUT http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits HTTP/1.1
Host: mender-useradm:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "limit": 123
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits',
{
  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 'http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.put('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits', 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','http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits', 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("http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits");
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", "http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PUT /tenants/{tenant_id}/limits

Update information about tenant limits

Body parameter

{
  "limit": 123
}

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.
body body Limits true

Example responses

400 Response

{
  "error": "missing Authorization header"
}

Responses

Status Meaning Description Schema
204 No Content Limit information updated. None
400 Bad Request The request body is malformed. Error
500 Internal Server Error Internal server error. Error

Clear Tenant Limits

Code samples

# You can also use wget
curl -X DELETE http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits \
  -H 'Accept: application/json'

DELETE http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits HTTP/1.1
Host: mender-useradm:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits',
{
  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'
}

result = RestClient.delete 'http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.delete('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits', 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('DELETE','http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits', 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("http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits");
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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/limits", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /tenants/{tenant_id}/limits

Remove limits from tenant

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.

Example responses

500 Response

{
  "error": "missing Authorization header"
}

Responses

Status Meaning Description Schema
204 No Content Limits information deleted. None
500 Internal Server Error Internal server error. Error

Show Tenant Plan And Limits

Code samples

# You can also use wget
curl -X GET http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/plan_binding \
  -H 'Accept: application/json'

GET http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/plan_binding HTTP/1.1
Host: mender-useradm:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/plan_binding',
{
  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 'http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/plan_binding',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/plan_binding', 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','http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/plan_binding', 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("http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/plan_binding");
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", "http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/plan_binding", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /tenants/{tenant_id}/plan_binding

Get plan and limits information for given tenant

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.

Example responses

200 Response

{
  "plan": {
    "product": "Mender",
    "name": "mender-enterprise",
    "display_name": "Mender Enterprise",
    "features": {
      "rbac": true,
      "audit_logs": true
    }
  },
  "limits": {
    "devices": 10,
    "users": 2,
    "audit_logs_days": 2
  }
}

Responses

Status Meaning Description Schema
200 OK Successful response - a plan information is returned. PlanBindingDetails
400 Bad Request Invalid parameters. See error message for details. Error
500 Internal Server Error Internal server error. Error

Update Tenant Plan And Limits

Code samples

# You can also use wget
curl -X PUT http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/plan_binding \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

PUT http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/plan_binding HTTP/1.1
Host: mender-useradm:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "plan_name": "mender-enterprise",
  "limits": {
    "devices": 10,
    "users": 2,
    "audit_logs_days": 2
  }
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/plan_binding',
{
  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 'http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/plan_binding',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.put('http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/plan_binding', 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','http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/plan_binding', 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("http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/plan_binding");
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", "http://mender-useradm:8080/api/internal/v1/useradm/tenants/{tenant_id}/plan_binding", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PUT /tenants/{tenant_id}/plan_binding

Update information about tenant plan and limits

Body parameter

{
  "plan_name": "mender-enterprise",
  "limits": {
    "devices": 10,
    "users": 2,
    "audit_logs_days": 2
  }
}

Parameters

Name In Type Required Description
tenant_id path string true Tenant ID.
body body PlanBinding true

Example responses

400 Response

{
  "error": "missing Authorization header"
}

Responses

Status Meaning Description Schema
204 No Content Plan and limits information updated. None
400 Bad Request The request body is malformed. Error
500 Internal Server Error Internal server error. Error

Assign Tenants Internal

Code samples

# You can also use wget
curl -X POST http://mender-useradm:8080/api/internal/v1/useradm/users/{id}/assign \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-useradm:8080/api/internal/v1/useradm/users/{id}/assign HTTP/1.1
Host: mender-useradm:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "tenant_ids": [
    "65c76fd6e15517b2f0fbfdf1",
    "65c76fda5e6177ca400a9d4d"
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-useradm:8080/api/internal/v1/useradm/users/{id}/assign',
{
  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 'http://mender-useradm:8080/api/internal/v1/useradm/users/{id}/assign',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.post('http://mender-useradm:8080/api/internal/v1/useradm/users/{id}/assign', 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','http://mender-useradm:8080/api/internal/v1/useradm/users/{id}/assign', 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("http://mender-useradm:8080/api/internal/v1/useradm/users/{id}/assign");
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", "http://mender-useradm:8080/api/internal/v1/useradm/users/{id}/assign", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /users/{id}/assign

Assign tenants to a given user

Body parameter

{
  "tenant_ids": [
    "65c76fd6e15517b2f0fbfdf1",
    "65c76fda5e6177ca400a9d4d"
  ]
}

Parameters

Name In Type Required Description
id path string true User id to assign.
body body TenantIdsData true tenantIdsData.

Example responses

400 Response

{
  "error": "missing Authorization header"
}

Responses

Status Meaning Description Schema
200 OK User assigned. None
400 Bad Request Operation is invalid, see error message. Error
404 Not Found The user was not found. Error
500 Internal Server Error Internal server error. Error

Schemas

Error

{
  "error": "missing Authorization header"
}

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.

TenantNew

{
  "tenant_id": "1234"
}

Tenant configuration.

Properties
Name Type Required Description
tenant_id string false ID of given tenant.

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.
login_ts string(date-time) false Timestamp of the last successful login.
verified boolean false Indicates if the user's email address has been verified.
tfa_status string false User Two Factor Authentication status.
roles [string] false List of user roles.
» ListOfRoles string false Role name

UserWithTenantInfo

{
  "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",
  "tenant_id": "84430f18-d464-5194-b8ef-b1a15161bb4c",
  "tenant_ids": [
    "84430f18-d464-5194-b8ef-b1a15161bb4c",
    "2c481d66-4bd0-43ad-a8b9-61503611c745"
  ]
}

Properties

allOf

Name Type Required Description
anonymous User false User descriptor.

and

Name Type Required Description
anonymous TenantInfo false

TenantInfo

{
  "tenant_id": "string",
  "tenant_ids": [
    "string"
  ]
}

Properties
Name Type Required Description
tenant_id string false Tenant identifier of a tenant, user will log in to by default.
tenant_ids [string] false List of tenant Ids user can login to.

UserNew

{
  "email": "user@acme.com",
  "password": "secret",
  "propagate": false,
  "magic_id": "a30a780b-b843-5344-80e3-0fd95a4f6fc3"
}

New user descriptor.

Properties
Name Type Required Description
email string(email) true User's email.
password string true User's password.
propagate boolean false This paramter is deprecated, the propagation of user information to tenant adm is disabled
permanently.
magic_id string(uuid) false Unique id to allow a user to log in using a magic link

Emails

{
  "emails": [
    "demo@example.com",
    "admin@example.com"
  ]
}

Properties
Name Type Required Description
emails [string] true List of users emails.

Limits

{
  "limit": 123
}

Tenant account limits.

Properties
Name Type Required Description
users Limit true Tenant account limits.

Limit

{
  "count": 10,
  "max": 20
}

Tenant account limits.

Properties
Name Type Required Description
count integer false
max integer true

Plan

{
  "product": "Mender",
  "name": "mender-enterprise",
  "display_name": "Mender Enterprise",
  "features": {
    "rbac": true,
    "audit_logs": false
  }
}

Plan descriptor.

Properties
Name Type Required Description
name string true Unique name of the plan.
display_name string true Short information about the plan.
features Features true Features descriptor.

Features

{
  "rbac": true,
  "audit_logs": false,
  "dynamic_groups": false,
  "terminal": true,
  "file_transfer": true,
  "configuration": true,
  "monitoring": true
}

Features descriptor.

Properties
Name Type Required Description
rbac boolean false
audit_logs boolean false
dynamic_groups boolean false
terminal boolean false
file_transfer boolean false
configuration boolean false
monitoring boolean false

PlanLimits

{
  "devices": 10,
  "users": 2,
  "audit_logs_days": 2
}

Plan limits descriptor.

Properties
Name Type Required Description
devices integer false
users integer false
audit_logs_days integer false

PlanBinding

{
  "plan_name": "mender-enterprise",
  "limits": {
    "devices": 10,
    "users": 2,
    "audit_logs_days": 2
  }
}

Combination of plan and limits objects.

Properties
Name Type Required Description
plan_name string false
limits PlanLimits false Plan limits descriptor.

PlanBindingDetails

{
  "plan": {
    "product": "Mender",
    "name": "mender-enterprise",
    "display_name": "Mender Enterprise",
    "features": {
      "rbac": true,
      "audit_logs": true
    }
  },
  "limits": {
    "devices": 10,
    "users": 2,
    "audit_logs_days": 2
  }
}

Combination of plan and limits objects.

Properties
Name Type Required Description
plan Plan false Plan descriptor.
limits PlanLimits false Plan limits descriptor.

TenantIdsData

{
  "tenant_ids": [
    "65c76fd6e15517b2f0fbfdf1",
    "65c76fda5e6177ca400a9d4d"
  ]
}

Tenant ids data.

Properties
Name Type Required Description
tenant_ids [string] false
» ListOfIds string false tenant ids

TenantId

{
  "tenant_id": [
    "65c76fd6e15517b2f0fbfdf1"
  ]
}

Tenant ids data.

Properties
Name Type Required Description
tenant_id string false

Workflows

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 workflow management. Intended for use by other services.

Base URLs:

Check Liveliness

Code samples

# You can also use wget
curl -X GET http://mender-workflows-server:8080/status \
  -H 'Accept: application/json'

GET http://mender-workflows-server:8080/status HTTP/1.1
Host: mender-workflows-server:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-workflows-server:8080/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'
}

result = RestClient.get 'http://mender-workflows-server:8080/status',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-workflows-server:8080/status', 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','http://mender-workflows-server:8080/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("http://mender-workflows-server:8080/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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-workflows-server:8080/status", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /status

Check if service API is alive and serving requests

Example responses

Successful response.

{
  "status": "ok"
}

500 Response

{
  "error": "failed: JSON payload is empty"
}

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
» id string false
» name string false

Check Health

Code samples

# You can also use wget
curl -X GET http://mender-workflows-server:8080/health \
  -H 'Accept: application/json'

GET http://mender-workflows-server:8080/health HTTP/1.1
Host: mender-workflows-server:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-workflows-server:8080/health',
{
  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 'http://mender-workflows-server:8080/health',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-workflows-server:8080/health', 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','http://mender-workflows-server:8080/health', 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("http://mender-workflows-server:8080/health");
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", "http://mender-workflows-server:8080/health", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /health

Check if service and all operational dependencies are healthy.

Example responses

500 Response

{
  "error": "failed: JSON payload is empty"
}

Responses

Status Meaning Description Schema
204 No Content Service is healthy. None
500 Internal Server Error Internal Server Error. Error
502 Bad Gateway Service is temporarily unavailable (currently unhealthy). Error

Delete tenant data

Code samples

# You can also use wget
curl -X DELETE http://mender-workflows-server:8080/api/v1/tenants/{id} \
  -H 'Accept: application/json'

DELETE http://mender-workflows-server:8080/api/v1/tenants/{id} HTTP/1.1
Host: mender-workflows-server:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-workflows-server:8080/api/v1/tenants/{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'
}

result = RestClient.delete 'http://mender-workflows-server:8080/api/v1/tenants/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.delete('http://mender-workflows-server:8080/api/v1/tenants/{id}', 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('DELETE','http://mender-workflows-server:8080/api/v1/tenants/{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("http://mender-workflows-server:8080/api/v1/tenants/{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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://mender-workflows-server:8080/api/v1/tenants/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /api/v1/tenants/{id}

Delete all the data belonging to a given tenant

Removes all the jobs that have the given tenant id in input parameters.

Parameters

Name In Type Required Description
id path string true Tenant id to remove.

Example responses

500 Response

{
  "error": "failed: JSON payload is empty"
}

Responses

Status Meaning Description Schema
204 No Content Tenant data removed None
500 Internal Server Error Internal Server Error. Error

Start Workflow

Code samples

# You can also use wget
curl -X POST http://mender-workflows-server:8080/api/v1/workflow/{name} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-workflows-server:8080/api/v1/workflow/{name} HTTP/1.1
Host: mender-workflows-server:8080
Content-Type: application/json
Accept: application/json

const inputBody = '[
  {
    "name": "key",
    "value": "parameter"
  }
]';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-workflows-server:8080/api/v1/workflow/{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'
}

result = RestClient.post 'http://mender-workflows-server:8080/api/v1/workflow/{name}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.post('http://mender-workflows-server:8080/api/v1/workflow/{name}', 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','http://mender-workflows-server:8080/api/v1/workflow/{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("http://mender-workflows-server:8080/api/v1/workflow/{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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://mender-workflows-server:8080/api/v1/workflow/{name}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /api/v1/workflow/{name}

Start a new workflow

Starts a new workflow given by the name path-parameter.

Body parameter

[
  {
    "name": "key",
    "value": "parameter"
  }
]

Parameters

Name In Type Required Description
name path string true Workflow identifier.
body body InputParameter true Contains the definition of the job to be started.

Example responses

201 Response

{
  "id": "string",
  "name": "string"
}

Responses

Status Meaning Description Schema
201 Created Workflow created successfully Inline
400 Bad Request Invalid Request. Error
404 Not Found Not Found. Error
Response Schema

Status Code 201

Name Type Required Restrictions Description
» id string false
» name string false

Start Batch Workflows

Code samples

# You can also use wget
curl -X POST http://mender-workflows-server:8080/api/v1/workflow/{name}/batch \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-workflows-server:8080/api/v1/workflow/{name}/batch HTTP/1.1
Host: mender-workflows-server:8080
Content-Type: application/json
Accept: application/json

const inputBody = '[
  [
    {
      "name": "key",
      "value": "parameter"
    }
  ]
]';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-workflows-server:8080/api/v1/workflow/{name}/batch',
{
  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 'http://mender-workflows-server:8080/api/v1/workflow/{name}/batch',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.post('http://mender-workflows-server:8080/api/v1/workflow/{name}/batch', 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','http://mender-workflows-server:8080/api/v1/workflow/{name}/batch', 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("http://mender-workflows-server:8080/api/v1/workflow/{name}/batch");
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", "http://mender-workflows-server:8080/api/v1/workflow/{name}/batch", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /api/v1/workflow/{name}/batch

Start a batch of workflows

Starts a new workflow given by the name path-parameter.

Body parameter

[
  [
    {
      "name": "key",
      "value": "parameter"
    }
  ]
]

Parameters

Name In Type Required Description
name path string true Workflow identifier.
body body array[array] true Contains the definition of the job to be started.

Example responses

201 Response

[
  {
    "id": "string",
    "name": "string",
    "error": "string"
  }
]

Responses

Status Meaning Description Schema
201 Created Workflows created successfully Inline
400 Bad Request Invalid Request. Error
404 Not Found Not Found. Error
Response Schema

Status Code 201

Name Type Required Restrictions Description
» id string false
» name string false
» error string false

Workflow Status

Code samples

# You can also use wget
curl -X GET http://mender-workflows-server:8080/api/v1/workflow/{name}/{id} \
  -H 'Accept: application/json'

GET http://mender-workflows-server:8080/api/v1/workflow/{name}/{id} HTTP/1.1
Host: mender-workflows-server:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-workflows-server:8080/api/v1/workflow/{name}/{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'
}

result = RestClient.get 'http://mender-workflows-server:8080/api/v1/workflow/{name}/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-workflows-server:8080/api/v1/workflow/{name}/{id}', 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','http://mender-workflows-server:8080/api/v1/workflow/{name}/{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("http://mender-workflows-server:8080/api/v1/workflow/{name}/{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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-workflows-server:8080/api/v1/workflow/{name}/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /api/v1/workflow/{name}/{id}

Gets the workflow status for the given id.

Gets the workflow status for the given workflow name and id provided by the path parameters.

Parameters

Name In Type Required Description
name path string true Workflow identifier.
id path string true Job identifier

Example responses

200 Response

{
  "id": "string",
  "workflowName": "string",
  "inputParameters": [
    {
      "name": "key",
      "value": "parameter"
    }
  ],
  "status": "string",
  "results": [
    {
      "success": true,
      "cli": {
        "command": [
          "string"
        ],
        "output": "string",
        "error": "string",
        "exitCode": 0
      },
      "request": {
        "statusCode": 0,
        "body": "string"
      },
      "response": {
        "uri": "string",
        "method": "string",
        "headers": [
          "string"
        ],
        "body": "string"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successful query JobStatus
404 Not Found Not Found. Error

List Workflows

Code samples

# You can also use wget
curl -X GET http://mender-workflows-server:8080/api/v1/metadata/workflows \
  -H 'Accept: application/json'

GET http://mender-workflows-server:8080/api/v1/metadata/workflows HTTP/1.1
Host: mender-workflows-server:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-workflows-server:8080/api/v1/metadata/workflows',
{
  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 'http://mender-workflows-server:8080/api/v1/metadata/workflows',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-workflows-server:8080/api/v1/metadata/workflows', 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','http://mender-workflows-server:8080/api/v1/metadata/workflows', 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("http://mender-workflows-server:8080/api/v1/metadata/workflows");
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", "http://mender-workflows-server:8080/api/v1/metadata/workflows", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /api/v1/metadata/workflows

Get all workflow definitions

Example responses

200 Response

[
  {
    "name": "string",
    "description": "string",
    "version": 0,
    "schemaversion": 0,
    "tasks": [
      {
        "name": "string",
        "type": "string",
        "retries": 0,
        "retryDelaySeconds": 0,
        "requires": [
          "string"
        ],
        "cli": {
          "command": [
            "string"
          ],
          "executionTimeOut": 0
        },
        "http": {
          "uri": "string",
          "method": "string",
          "contentType": "string",
          "body": "string",
          "json": {},
          "headers": {},
          "statusCodes": [
            0
          ],
          "connectionTimeOut": 0,
          "readTimeOut": 0
        }
      }
    ],
    "inputParameters": [
      "string"
    ]
  }
]

Responses

Status Meaning Description Schema
200 OK Successful response Inline
Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [Workflow] false
» name string true
» description string false
» version integer true
» schemaversion integer false
» tasks [Task] true [Task definition]
»» name string true
»» type string true
»» retries integer false
»» retryDelaySeconds integer false
»» requires [string] false
»» cli CLIParams false CLI parameters
»»» command [string] false
»»» executionTimeOut integer false
»» http HTTPParams false HTTP parameters
»»» uri string false
»»» method string false
»»» contentType string false
»»» body string false
»»» json object false
»»» headers object false
»»» statusCodes [integer] false
»»» connectionTimeOut integer false
»»» readTimeOut integer false
» inputParameters [string] false

Register Workflow

Code samples

# You can also use wget
curl -X POST http://mender-workflows-server:8080/api/v1/metadata/workflows \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST http://mender-workflows-server:8080/api/v1/metadata/workflows HTTP/1.1
Host: mender-workflows-server:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "name": "string",
  "description": "string",
  "version": 0,
  "schemaversion": 0,
  "tasks": [
    {
      "name": "string",
      "type": "string",
      "retries": 0,
      "retryDelaySeconds": 0,
      "requires": [
        "string"
      ],
      "cli": {
        "command": [
          "string"
        ],
        "executionTimeOut": 0
      },
      "http": {
        "uri": "string",
        "method": "string",
        "contentType": "string",
        "body": "string",
        "json": {},
        "headers": {},
        "statusCodes": [
          0
        ],
        "connectionTimeOut": 0,
        "readTimeOut": 0
      }
    }
  ],
  "inputParameters": [
    "string"
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('http://mender-workflows-server:8080/api/v1/metadata/workflows',
{
  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 'http://mender-workflows-server:8080/api/v1/metadata/workflows',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.post('http://mender-workflows-server:8080/api/v1/metadata/workflows', 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','http://mender-workflows-server:8080/api/v1/metadata/workflows', 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("http://mender-workflows-server:8080/api/v1/metadata/workflows");
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", "http://mender-workflows-server:8080/api/v1/metadata/workflows", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /api/v1/metadata/workflows

Register a new workflow

Body parameter

{
  "name": "string",
  "description": "string",
  "version": 0,
  "schemaversion": 0,
  "tasks": [
    {
      "name": "string",
      "type": "string",
      "retries": 0,
      "retryDelaySeconds": 0,
      "requires": [
        "string"
      ],
      "cli": {
        "command": [
          "string"
        ],
        "executionTimeOut": 0
      },
      "http": {
        "uri": "string",
        "method": "string",
        "contentType": "string",
        "body": "string",
        "json": {},
        "headers": {},
        "statusCodes": [
          0
        ],
        "connectionTimeOut": 0,
        "readTimeOut": 0
      }
    }
  ],
  "inputParameters": [
    "string"
  ]
}

Parameters

Name In Type Required Description
body body Workflow true Workflow definition.

Example responses

400 Response

{
  "error": "failed: JSON payload is empty"
}

Responses

Status Meaning Description Schema
201 Created Successful response. None
400 Bad Request Invalid Request. Error
409 Conflict Conflict, record already exists. Error

Job Structure

Code samples

# You can also use wget
curl -X GET http://mender-workflows-server:8080/api/v1/jobs/{id} \
  -H 'Accept: application/json'

GET http://mender-workflows-server:8080/api/v1/jobs/{id} HTTP/1.1
Host: mender-workflows-server:8080
Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('http://mender-workflows-server:8080/api/v1/jobs/{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'
}

result = RestClient.get 'http://mender-workflows-server:8080/api/v1/jobs/{id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('http://mender-workflows-server:8080/api/v1/jobs/{id}', 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','http://mender-workflows-server:8080/api/v1/jobs/{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("http://mender-workflows-server:8080/api/v1/jobs/{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"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://mender-workflows-server:8080/api/v1/jobs/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /api/v1/jobs/{id}

Gets the job for the given id.

Gets the job object for the given job id.

Parameters

Name In Type Required Description
id path string true Job identifier

Example responses

200 Response

{
  "id": "string",
  "workflowName": "string",
  "inputParameters": [
    {
      "name": "key",
      "value": "parameter"
    }
  ],
  "status": "string",
  "results": [
    {
      "success": true,
      "cli": {
        "command": [
          "string"
        ],
        "output": "string",
        "error": "string",
        "exitCode": 0
      },
      "request": {
        "statusCode": 0,
        "body": "string"
      },
      "response": {
        "uri": "string",
        "method": "string",
        "headers": [
          "string"
        ],
        "body": "string"
      }
    }
  ],
  "insert_time": "2019-08-24T14:15:22Z",
  "version": "string"
}

Responses

Status Meaning Description Schema
200 OK Successful query JobObject
404 Not Found Not Found. Error

Schemas

Error

{
  "error": "failed: JSON payload is empty"
}

Error descriptor.

Properties
Name Type Required Description
error string false Description of the error.

CLIParams

{
  "command": [
    "string"
  ],
  "executionTimeOut": 0
}

CLI parameters

Properties
Name Type Required Description
command [string] false
executionTimeOut integer false

HTTPParams

{
  "uri": "string",
  "method": "string",
  "contentType": "string",
  "body": "string",
  "json": {},
  "headers": {},
  "statusCodes": [
    0
  ],
  "connectionTimeOut": 0,
  "readTimeOut": 0
}

HTTP parameters

Properties
Name Type Required Description
uri string false
method string false
contentType string false
body string false
json object false
headers object false
statusCodes [integer] false
connectionTimeOut integer false
readTimeOut integer false

Task

{
  "name": "string",
  "type": "string",
  "retries": 0,
  "retryDelaySeconds": 0,
  "requires": [
    "string"
  ],
  "cli": {
    "command": [
      "string"
    ],
    "executionTimeOut": 0
  },
  "http": {
    "uri": "string",
    "method": "string",
    "contentType": "string",
    "body": "string",
    "json": {},
    "headers": {},
    "statusCodes": [
      0
    ],
    "connectionTimeOut": 0,
    "readTimeOut": 0
  }
}

Task definition

Properties
Name Type Required Description
name string true
type string true
retries integer false
retryDelaySeconds integer false
requires [string] false
cli CLIParams false CLI parameters
http HTTPParams false HTTP parameters

Workflow

{
  "name": "string",
  "description": "string",
  "version": 0,
  "schemaversion": 0,
  "tasks": [
    {
      "name": "string",
      "type": "string",
      "retries": 0,
      "retryDelaySeconds": 0,
      "requires": [
        "string"
      ],
      "cli": {
        "command": [
          "string"
        ],
        "executionTimeOut": 0
      },
      "http": {
        "uri": "string",
        "method": "string",
        "contentType": "string",
        "body": "string",
        "json": {},
        "headers": {},
        "statusCodes": [
          0
        ],
        "connectionTimeOut": 0,
        "readTimeOut": 0
      }
    }
  ],
  "inputParameters": [
    "string"
  ]
}

Properties
Name Type Required Description
name string true
description string false
version integer true
schemaversion integer false
tasks [Task] true [Task definition]
inputParameters [string] false

InputParameter

{
  "name": "key",
  "value": "parameter"
}

Properties
Name Type Required Description
name string true
value string true

TaskResultCLI

{
  "command": [
    "string"
  ],
  "output": "string",
  "error": "string",
  "exitCode": 0
}

Properties
Name Type Required Description
command [string] false
output string false
error string false
exitCode integer false

TaskResultHTTPRequest

{
  "statusCode": 0,
  "body": "string"
}

Properties
Name Type Required Description
statusCode integer false
body string false

TaskResultHTTPResponse

{
  "uri": "string",
  "method": "string",
  "headers": [
    "string"
  ],
  "body": "string"
}

Properties
Name Type Required Description
uri string false
method string false
headers [string] false
body string false

TaskResult

{
  "success": true,
  "cli": {
    "command": [
      "string"
    ],
    "output": "string",
    "error": "string",
    "exitCode": 0
  },
  "request": {
    "statusCode": 0,
    "body": "string"
  },
  "response": {
    "uri": "string",
    "method": "string",
    "headers": [
      "string"
    ],
    "body": "string"
  }
}

Properties
Name Type Required Description
success boolean false
cli TaskResultCLI false
request TaskResultHTTPRequest false
response TaskResultHTTPResponse false

JobStatus

{
  "id": "string",
  "workflowName": "string",
  "inputParameters": [
    {
      "name": "key",
      "value": "parameter"
    }
  ],
  "status": "string",
  "results": [
    {
      "success": true,
      "cli": {
        "command": [
          "string"
        ],
        "output": "string",
        "error": "string",
        "exitCode": 0
      },
      "request": {
        "statusCode": 0,
        "body": "string"
      },
      "response": {
        "uri": "string",
        "method": "string",
        "headers": [
          "string"
        ],
        "body": "string"
      }
    }
  ]
}

Properties
Name Type Required Description
id string false
workflowName string false
inputParameters [InputParameter] false
status string false
results [TaskResult] false

JobObject

{
  "id": "string",
  "workflowName": "string",
  "inputParameters": [
    {
      "name": "key",
      "value": "parameter"
    }
  ],
  "status": "string",
  "results": [
    {
      "success": true,
      "cli": {
        "command": [
          "string"
        ],
        "output": "string",
        "error": "string",
        "exitCode": 0
      },
      "request": {
        "statusCode": 0,
        "body": "string"
      },
      "response": {
        "uri": "string",
        "method": "string",
        "headers": [
          "string"
        ],
        "body": "string"
      }
    }
  ],
  "insert_time": "2019-08-24T14:15:22Z",
  "version": "string"
}

Properties
Name Type Required Description
id string false
workflowName string false
inputParameters [InputParameter] false
status string false
results [TaskResult] false
insert_time string(date-time) false
version string false