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:

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.my_update_bucket.com/image_123",
      "expire": "2016-03-11T13:03:17.063493443Z"
    },
    "device_types_compatible": [
      "rspi",
      "rspi2",
      "rspi0"
    ]
  }
}

400 Response

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

Responses

Status Meaning Description Schema
200 OK Successful response. DeploymentInstructions
204 No Content No updates for device. None
400 Bad Request Invalid Request. Error
404 Not Found Not Found. Error
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
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
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
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).

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.my_update_bucket.com/image_123",
      "expire": "2016-03-11T13:03:17.063493443Z"
    },
    "device_types_compatible": [
      "rspi",
      "rspi2",
      "rspi0"
    ]
  }
}

Properties
Name Type Required Description
id string true Deployment ID
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.

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 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 deploymen and has give 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 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 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 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 deploymen and has give 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 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 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.
» 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.
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
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 = '[
  "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

[
  "string"
]

Parameters

Name In Type Required Description
body body array[string] true Deployment identifier

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
    }
  },
  {
    "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
    }
  }
]

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 DeploymentStatistics 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 Conflict. 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
}

404 Response

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

Responses

Status Meaning Description Schema
200 OK OK DeploymentStatistics
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error

List 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",
    "device_type": "Raspberry Pi 3",
    "log": false,
    "state": "installing",
    "substate": "installing.enter;script:foo-bar"
  }
]

Responses

Status Meaning Description Schema
200 OK OK Inline
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error
Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [Device] false
» id string true Device identifier.
» finished string(date-time) false
» status DeviceStatus true
» created string(date-time) false
» device_type string false
» log boolean true Availability of the device's deployment log.
» state string false State reported by device
» substate string false Additional state information
Enumerated Values
Property Value
status 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 list of all devices and their respective status for the deployment with the given ID. *

Parameters

Name In Type Required Description
deployment_id path string true Deployment identifier.
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

Example responses

200 Response

[
  {
    "id": "00a0c91e6-7dec-11d0-a765-f81d4faebf6",
    "finished": "2016-03-11T13:03:17.063493443Z",
    "status": "installing",
    "created": "2016-02-11T13:03:17.063493443Z",
    "device_type": "Raspberry Pi 3",
    "log": false,
    "state": "installing",
    "substate": "installing.enter;script:foo-bar"
  }
]

Responses

Status Meaning Description Schema
200 OK OK Inline
401 Unauthorized Unauthorized. None
404 Not Found Not Found. Error
500 Internal Server Error Internal Server Error. Error
Response Schema

Status Code 200

Name Type Required Restrictions Description
anonymous [Device] false
» id string true Device identifier.
» finished string(date-time) false
» status DeviceStatus true
» created string(date-time) false
» device_type string false
» log boolean true Availability of the device's deployment log.
» state string false State reported by device
» substate string false Additional state information
Enumerated Values
Property Value
status 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

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

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

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

Returns a collection of releases, allows filtering by release name.

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

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": {
          "type_info": {
            "type": "rootfs"
          }
        },
        "signed": false,
        "updates": {
          "type_info": "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": {
          "type_info": {
            "type": "rootfs"
          }
        },
        "signed": false,
        "updates": {
          "type_info": "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": {
          "type_info": {
            "type": "rootfs"
          }
        },
        "signed": false,
        "updates": {
          "type_info": "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 *

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.
description query string false Release description filter.
device_type query string false Release 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 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 name:asc
sort name:desc
sort modified:asc
sort modified: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": {
          "type_info": {
            "type": "rootfs"
          }
        },
        "signed": false,
        "updates": {
          "type_info": "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": {
          "type_info": {
            "type": "rootfs"
          }
        },
        "signed": false,
        "updates": {
          "type_info": "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": {
          "type_info": {
            "type": "rootfs"
          }
        },
        "signed": false,
        "updates": {
          "type_info": "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 known 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. *

Returns a collection of all artifacts.

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": {
      "type_info": {
        "type": "rootfs"
      }
    },
    "signed": false,
    "updates": {
      "type_info": "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
»» 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"
}

Responses

Status Meaning Description Schema
201 Created Artifact uploaded. None
400 Bad Request Invalid Request. Error
401 Unauthorized Unauthorized. None
500 Internal Server Error Internal Server Error. Error
Response Headers
Status Header Type Format Description
201 Location string URL of the newly uploaded artifact.

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": {
      "type_info": {
        "type": "rootfs"
      }
    },
    "signed": false,
    "updates": {
      "type_info": "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
»» 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.

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 Type-specific arguments used to generate the artifact.
» file body string(binary) true Raw file to be used to generate the artifact. It has to be the last part of request.
Enumerated Values
Parameter Value
» type single_file

Example responses

400 Response

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

Responses

Status Meaning Description Schema
201 Created Artifact generation request accepted and queued for processing. None
400 Bad Request Invalid Request. Error
401 Unauthorized Unauthorized. None
500 Internal Server Error Internal Server Error. Error
Response Headers
Status Header Type Format Description
201 Location string URL of the artifact going to be generated.

Show Artifact

Code samples

# You can also use wget
curl -X GET https://hosted.mender.io/api/management/v1/deployments/artifacts/{id} \
  -H 'Accept: application/json' \
  -H 'Authorization: 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": {
    "type_info": {
      "type": "rootfs"
    }
  },
  "signed": false,
  "updates": {
    "type_info": "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

Schemas

Error

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

Error descriptor.

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

NewDeployment

{
  "name": "production",
  "artifact_name": "Application 0.0.1",
  "devices": [
    "00a0c91e6-7dec-11d0-a765-f81d4faebf6"
  ],
  "phases": [
    {
      "batch_size": 5,
      "start_ts": "2020-07-06T15:04:49.114046203+02:00"
    },
    {
      "batch_size": 15,
      "start_ts": "2020-07-06T16:04:49.114046203+02:00"
    },
    {
      "start_ts": "2020-07-06T17:04:49.114046203+02:00"
    }
  ],
  "retries": 3
}

Properties
Name Type Required Description Plans
name string true 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.
phases [NewDeploymentPhase] false professional, enterprise
retries integer false The number of times a device can retry the deployment in case of failure, defaults to 0
update_control_map object false A valid JSON object defining the update control map.
NOTE: Available only in the Enterprise plan.
enterprise

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
phases [NewDeploymentPhase] false professional, enterprise
retries integer false The number of times a device can retry the deployment in case of failure, defaults to 0
update_control_map object false A valid JSON object defining the update control map.
NOTE: Available only in the Enterprise plan.
enterprise

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

Properties
Name Type Required Description
batch_size integer false Percentage of devices to update in the phase.
This field is optional for the last phase.
The last phase will contain the rest of the devices.
Note that if the percentage of devices entered does not
add up to a whole number of devices it is rounded down,
and in the case it is rounded down to zero, a 400 error
will be returned. This is mostly a concern when the deployment
consists of a low number of devices, like say 5 percent of 11
devices will round to zero, and an error is returned by the server.
start_ts string(date-time) false Start date of a phase.
Can be skipped for the first phase of a new deployment definition ('start immediately').

DeploymentPhase

{
  "application/json": {
    "id": "foo",
    "start_ts": "2020-07-06T15:04:49.114046203+02:00",
    "batch_size": 5,
    "device_count": 42
  }
}

Properties
Name Type Required Description
id string false Phase identifier.
batch_size integer false Percentage of devices to update in the phase.
start_ts string(date-time) false Start date of a phase.
May be undefined for the first phase of a deployment.
device_count integer false Number of devices which already requested an update within this phase.

DeploymentStatistics

{
  "success": 3,
  "pending": 1,
  "failure": 0,
  "downloading": 1,
  "installing": 2,
  "rebooting": 3,
  "noartifact": 0,
  "already-installed": 0,
  "aborted": 0,
  "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",
  "device_type": "Raspberry Pi 3",
  "log": false,
  "state": "installing",
  "substate": "installing.enter;script:foo-bar"
}

Properties
Name Type Required Description
id string true Device identifier.
finished string(date-time) false
status DeviceStatus true
created string(date-time) false
device_type string false
log boolean true Availability of the device's deployment log.
state string false State reported by device
substate string false Additional state information

ArtifactUpdate

{
  "description": "Some description"
}

Artifact information update.

Properties
Name Type Required Description
description string false

ArtifactTypeInfo

{
  "type": "string"
}

Information about update type.

Properties
Name Type Required Description
type string false

UpdateFile

{
  "name": "string",
  "checksum": "string",
  "size": 0,
  "date": "2019-08-24T14:15:22Z"
}

Information about particular update file.

Properties
Name Type Required Description
name string false
checksum string false
size integer false
date string(date-time) false

Update

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

Single updated to be applied.

Properties
Name Type Required Description
type_info ArtifactTypeInfo false Information about update type.
files [UpdateFile] false [Information about particular update file.
]
meta_data object false meta_data is an object of unknown structure as this is dependent of update type (also custom defined by user)

ArtifactInfo

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

Information about artifact format and version.

Properties
Name Type Required Description
format string false
version integer false

Artifact

{
  "id": "0c13a0e6-6b63-475d-8260-ee42a590e8ff",
  "name": "Application 1.0.0",
  "description": "Johns Monday test build",
  "device_types_compatible": [
    "Beagle Bone"
  ],
  "info": {
    "type_info": {
      "type": "rootfs"
    }
  },
  "signed": false,
  "updates": {
    "type_info": "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

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": {
          "type_info": {
            "type": "rootfs"
          }
        },
        "signed": false,
        "updates": {
          "type_info": "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": {
          "type_info": {
            "type": "rootfs"
          }
        },
        "signed": false,
        "updates": {
          "type_info": "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": {
        "type_info": {
          "type": "rootfs"
        }
      },
      "signed": false,
      "updates": {
        "type_info": "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": {
        "type_info": {
          "type": "rootfs"
        }
      },
      "signed": false,
      "updates": {
        "type_info": "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.
artifacts [Artifact] false List of artifacts for this release.

FilterPredicate

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

Attribute filter predicate

Properties
Name Type Required Description
scope string true The scope of the attribute.

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

Attribute type is implicit, inferred from the JSON type.

Supported types: number, string, array of numbers, array of strings.
Mixed arrays are not allowed.
Enumerated Values
Property Value
type $eq
type $gt
type $gte
type $in
type $lt
type $lte
type $ne
type $nin
type $exists

Filter

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

Inventory filter assigned to the deployment

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

Deployments v2

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

Version 2 of the API for deployments management. Intended for use by the web GUI.

Base URLs:

Create Deployment

Code samples

# You can also use wget
curl -X POST https://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
422 Unprocessable Entity Unprocessable Entity. Error
500 Internal Server Error Internal Server Error. Error
Response Headers
Status Header Type Format Description
201 Location string URL of the newly created deployment.

Schemas

Error

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

Error descriptor.

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

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

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

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

Responses

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

Status Code 200

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

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

The attributes are completely vendor-specific, the provided ones are just an example.
In reference implementation structure contains vendor-selected fields,
such as MACs, serial numbers, etc.
»» status string false
»» ts string(date-time) false Created timestamp
»» 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
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",
    "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
  }
]

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

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

Schemas

Status

{
  "status": "accepted"
}

Admission status of the device.

Properties
Name Type Required Description
status string true
Enumerated Values
Property Value
status pending
status accepted
status rejected
status preauthorized

Limit

{
  "limit": 123
}

Limit definition

Properties
Name Type Required Description
limit integer true

Device

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

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

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

AuthSet

{
  "id": "string",
  "pubkey": "string",
  "identity_data": {
    "mac": "00:01:02:03:04:05",
    "sku": "My Device 1",
    "sn": "SN1234567890"
  },
  "status": "pending",
  "ts": "2019-08-24T14:15:22Z",
  "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
identity_data IdentityData true Device identity attributes, in the form of a JSON structure.

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

IdentityData

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

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

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

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

Device 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 Inline
400 Bad Request Bad Request. Error
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(uuid) false
» configured ManagementAPIConfiguration false
»» additionalProperties string 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

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 {