# Using the Mender API: The Basics of the Management API

**URL:** <https://hub.mender.io/t/using-the-mender-api-the-basics-of-the-management-api/5562>\
**Category:** Mender\
**Tags:** api\
**Created:** [January 18, 2023, 3:52pm UTC](https://hub.mender.io/t/using-the-mender-api-the-basics-of-the-management-api/5562 "2023-01-18T15:52:03Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![karolina.beta](https://avatars.discourse-cdn.com/v4/letter/k/8baadc/32.png) [@karolina.beta](https://hub.mender.io/u/karolina.beta)\
**Post date:** [January 18, 2023, 3:52pm UTC](https://hub.mender.io/t/using-the-mender-api-the-basics-of-the-management-api/5562/1 "2023-01-18T15:52:03Z")

</div>

> **[Using the Mender API: The Basics of the Management API | Mender](https://mender.io/blog/using-the-mender-api-the-basics-of-the-management-api)**
>
> Api icons created by DinosoftLabs - Flaticon Customer engineer Alan Martinovic explores the basics of using the Mender API - specifically the management AP

 ![api](https://canada1.discourse-cdn.com/flex036/uploads/mender/original/2X/8/8cfdfd894fff2b7a40c8cfd6b981d558d31058b4.png)  
Api icons created by DinosoftLabs - Flaticon

### Customer engineer Alan Martinovic explores the basics of using the Mender API - specifically the management API

[Mender](https://mender.io/how-it-works) was designed with easy integration into CI CD pipelines and fleet management workflows in mind and this is also reflected in our open core business offering and in our **open source** offering. Open REST APIs are the practical manifestation of this. This article will provide you with all you need to quickly get started with the Mender API. Refer to the [Mender Docs](https://docs.mender.io/server-integration/using-the-apis) for full implementation details on the management API and the Device API.

## Overview of Mender API

The Mender API is separated into two categories:

- **Device API** - the IoT device which has the Mender client installed uses the device API to poll for and receive the updates
- **Management API** - these are what the UI uses and what you can leverage to create automations in your OTA software deployment workflows.

This tutorial will focus on the use of the Management API.

### Versioning

As you start reading through the [Management API documentation](https://docs.mender.io/api/#management-apis) you will notice that some sections are seemingly duplicated with a version number in front of it.

Those represent the higher version of the API.  
As described in the [Mender API docs](https://docs.mender.io/overview/compatibility#mender-server-and-client-api):

The higher version API contains a mix of old and new API endpoints. For endpoints which haven’t changed in the new version the previous version endpoints are assumed. Practically, this translates always using the highest API version available. If an endpoint is not there, the one from the previous API version is assumed.

### Authentication

To start working with the API, you will need to authenticate. Practically this means that getting a hold of a JWT token the server considers valid. Only with that token in your API calls will the server grant you access.

There are two ways to get the JWT token:

Directly generate a [Personal Access Token](https://mender.io/blog/personal-access-tokens-simplify-the-api-based-integration-with-hosted-mender) in Hosted Mender  
Call the `/api/management/v1/useradm/auth/login` API endpoint with your Hosted Mender username and password and have the server return the token for you.

The usage of a PAT is recommended when dealing with the API as it gives the flexibility by allowing to set an expiration period.

For this tutorial we will use the `username and password` approach to generate a PAT. From there the PAT will be used in the rest of the examples.[1]

## Hands on examples - bash

Assumptions: You’ve registered for the [Mender free trial](https://mender.io/demo) and successfully completed the [Get started](https://docs.mender.io/get-started) process.

The following tools are available in your command line:

- `curl` - to send the http requests
- `jq` - it will be used to parse the json files

### Authentication - getting the PAT

Generating a PAT requires an [API call](https://docs.mender.io/api/#management-api-user-administration-and-authentication-create-personal-access-token). To make this API call, we need to authenticate with a username and password.

```auto
USER= <----- The email you use to sign into Hosted Mender i.e. myuser@email.com
PASS= <----- The password you use to sign into Hosted Mender

# i.e.
# USER=user@email.com 
# PASS=123456

BASE_URL="https://hosted.mender.io/api/management/v1/useradm"
API_ENDPOINT=/auth/login

JWT_TEMP=$(curl -X POST -H "Content-Type: application/json;" -u "$USER:$PASS" $BASE_URL$API_ENDPOINT)

echo $JWT_TEMP

# A large string of random characters will be printed

```

Now that we can make API calls, let’s generate a PAT.

```auto
BASE_URL=https://hosted.mender.io/api/management/v1/useradm
API_ENDPOINT=/settings/tokens

UNIQUE=$(openssl rand -hex 5)

BODY_PARAMETER=$(cat << EOF 
{
  "name": "demo-pat-$UNIQUE",
  "expires_in": 7200
}
EOF
)

JWT=$(curl -X POST $BASE_URL$API_ENDPOINT \
  -H 'Content-Type: application/json' \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $JWT_TEMP" \
  -d "$BODY_PARAMETER")
  
echo $JWT

```

This PAT is also a JWT token that will be used in the examples.  
All future examples rely on the existence of the JWT environment variable.

### Example 1 - list all devices by their identity

The [Device Identity](https://docs.mender.io/overview/identity#the-identity-of-a-device) is:

> A unique set of key-value pairs produced by the device and unchangeable for the lifecycle of the device. It is generated by the script on the device located at `/usr/share/mender/identity/mender-device-identity`.

Not to be confused with [Device ID](https://docs.mender.io/overview/identity#the-identity-of-a-device) which is a:

> A unique, unchangeable identifier the server assigns internally to every device.

When using the API’s you are exposed to both of these identifiers, and for this example we’re interested in getting the Device Identity for all devices.

Let’s first get all the device data and store it in a file:

```auto
BASE_URL=https://hosted.mender.io/api/management/v2/devauth
API_ENDPOINT=/devices

curl -X GET $BASE_URL$API_ENDPOINT \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $JWT" > devices.json

jq length devices.json
# Outputs 1

```

In this example, 1 device is already accepted as part of the [Getting started](https://docs.mender.io/get-started).

Now as the json response is stored in the file, we need to understand its structure.

The response schema for the `/devices` endpoint is listed in the docs for the [List Devices API endpoint](https://docs.mender.io/api/#management-api-device-authentication-list-devices-responses).

Listing based on the value of `identity_data` will give us the answer we’re looking for.

```auto
jq '.[].identity_data' devices.json 

# OUTPUT:
#
#{
# "mac": "52:54:00:ce:34:5b"
#}

```

### Example 2 - get the inventory data of a device

In the previous example we’ve listed the Device Identities.  
Now we want to know the [inventory attributes](https://docs.mender.io/overview/inventory) of a specific device. The device inventory is:

> A customizable list of `key=value` pairs providing information about the device. The inventory `key=value` pairs are generated by the scripts located at `/usr/share/mender/inventory/` on the device. The device sends the updated inventory values to the server with the period defined by [InventoryPollIntervalSeconds](https://docs.mender.io/client-installation/configuration-file/configuration-options#inventorypollintervalseconds).

The [Get Device Inventory](https://docs.mender.io/api/#management-api-device-inventory-get-device-inventory) endpoint can be used for that. However it soon becomes obvious that we can’t use the Device Identity as input, instead what is needed is the Device ID.

The snippet below is a quick way to get the Device ID[2]:

```auto
DEVICE_IDENTITY="dc:a6:32:7d:9f:f2"
DEVICE_ID=$(jq -r '.[] | select(.identity_data.mac=="b8:27:eb:d6:95:af") | .id' devices.json)
echo $DEVICE_ID

```

With the Device ID available we can get the device inventory:

```auto
BASE_URL=https://hosted.mender.io/api/management/v1/inventory
API_ENDPOINT=/devices/$DEVICE_ID

curl -X GET $BASE_URL$API_ENDPOINT \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $JWT" > inventory-$DEVICE_IDENTITY.json

```

The device inventory is large so it won’t be listed here.  
You can print and examine it by running `jq . inventory-$DEVICE_IDENTITY.json`

### Example 3 - create a new user and assign it a new role

Let’s create a new user now using the [Create User API endpoint](https://docs.mender.io/api/#management-api-user-administration-and-authentication-create-user):

```auto
BASE_URL=https://hosted.mender.io/api/management/v1/useradm
API_ENDPOINT=/users

EMAIL="$(openssl rand -hex 5)@example-email.com"
PASSWORD=$(openssl rand -base64 10)

BODY_PARAMETER=$(cat << EOF 
{
  "email": "$EMAIL",
  "password": "$PASSWORD",
  "login": {}
}
EOF
)

curl -i -X POST $BASE_URL$API_ENDPOINT \
  -H 'Content-Type: application/json' \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $JWT" \
  -d "$BODY_PARAMETER"

```

The above command created the user. [3]  
Let’s locate the new user and get some information about them.  
We first need to get a list of all the users, and then filter out the one relevant to us:

```auto
BASE_URL=https://hosted.mender.io/api/management/v1/useradm
API_ENDPOINT=/users

curl -X GET $BASE_URL$API_ENDPOINT \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $JWT" > all-users.json

jq --arg EMAIL "$EMAIL" -r '.[] | select(.email==$EMAIL)' all-users.json

# OUTPUT:
# {
# "id": "22d01bc9-e67d-4a0c-81d1-2fc2061adff5",
# "email": "369a8650db@mender-api-blog.com",
# "tfa_status": "",
# "created_ts": "2022-12-13T13:38:59.228Z",
# "updated_ts": "2022-12-13T13:38:59.228Z",
# "roles": [
# "RBAC_ROLE_PERMIT_ALL"
# ]
# }

```

Mender Enterprise plan and [free trial](https://mender.io/demo) have a concept of [Role Based Access Control (RBAC)[([Role-Based Access Control | Mender documentation](https://docs.mender.io/overview/role.based.access.control)).

A Role is a set of permissions you can assign to a user. A user can have multiple Roles and a Role can be assigned to multiple different users.

Seems like our new user was created with an admin role [`RBAC_ROLE_PERMIT_ALL`].  
Let’s check the roles for something less permissive.

```auto
BASE_URL=https://hosted.mender.io/api/management/v1/useradm
API_ENDPOINT=/roles

curl -X GET $BASE_URL$API_ENDPOINT \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $JWT" | jq .[].name

```

The `RBAC_ROLE_OBSERVER` is a much more restrictive, read-only role.  
Let’s assign it to the new user instead.

```auto
USER_ID=$(jq --arg EMAIL "$EMAIL" -r '.[] | select(.email==$EMAIL) | .id' all-users.json)

BASE_URL=https://hosted.mender.io/api/management/v1/useradm
API_ENDPOINT=/users/$USER_ID

BODY_PARAMETER=$(cat << EOF 
{
  "roles": [
    "RBAC_ROLE_OBSERVER"
  ]
}
EOF
)

curl -X PUT $BASE_URL$API_ENDPOINT \
  -H 'Content-Type: application/json' \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $JWT" \
  -d "$BODY_PARAMETER"

```

Once the new role is set, let’s quickly call the [List users](https://docs.mender.io/api/#management-api-user-administration-and-authentication-list-users) again to confirm the change:

```auto
BASE_URL=https://hosted.mender.io/api/management/v1/useradm
API_ENDPOINT=/users

curl -X GET $BASE_URL$API_ENDPOINT \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $JWT" | jq --arg EMAIL "$EMAIL" -r '.[] | select(.email==$EMAIL)'

```

The output confirms the new user has the new role [`RBAC_ROLE_OBSERVER`].

## Try out the Mender API for yourself

The few examples in this tutorial provided a taste of what it’s like to use the [Mender API](https://docs.mender.io/api/#introduction). This only scratches the surface of what you can do with the API, but it provides a working reference you can copy and modify to explore the workings of other API endpoints.

[1] - if you have created your account using SSO (Github/Google/Microsoft) you will need to create the PAT using the UI.

[2] - please note that we’re assuming that the key for the Device identity is `mac` which is the default. If you modified this to another value, the script will need to be adjusted.

[3] - for return codes other then success (`201`) please take a look at the [list of responses](https://docs.mender.io/api/#management-api-user-administration-and-authentication-create-user-responses).
