NAV Navbar
Java C# Python JavaScript

Introduction

Pelion Device Management SDKs are Open Source libraries which provide a convenient way to develop applications that communicate with Pelion Device Management REST APIs.

The SDKs expose Pelion Device Management functionality, without needing to directly access the REST interface, using conventions and paradigms that should be familiar to a developer familiar with the supported languages. In some areas the SDKs also provide an additional degree of abstraction, which should make more complex tasks easier to implement in application code.

Language GitHub Repository Packages Reference Documentation
Python mbed-cloud-sdk-python PyPI Python
Java mbed-cloud-sdk-java Maven Central / JCenter Java
JavaScript / TypeScript mbed-cloud-sdk-javascript npm JavaScript / Typescript
C# / .NET mbed-cloud-sdk-dotnet NuGet C# / .Net

Context

This diagram shows the context of the SDKs fits in the larger picture of Pelion Device Management and application development.

Field covered

Contribution

Arm has a dedicated team to maintain and extend the SDKs. They are under active development to keep up to date with the latest improvements and features of the Pelion Device Management platform.

Contributions in the form of GitHub Pull Requests to any of the public repositories are very welcome. Alternatively, developers can report feature requests and bugs to the Arm team via GitHub issues.

Getting started

The aim of this section is to get a small script using a Pelion Device Management SDK communicating with the Pelion Device Management platform.

Prerequisites

  1. Follow the tutorial Connect to Pelion Device Management to connect your Mbed OS IoT device to Pelion Device Management.
  2. Follow the guide Access Device Management with API keys and create an API Key to use with the SDKs using the Pelion Device Management Portal.
  3. Setup a development environment suitable for the chosen language.

Installation

// example: initial setup
dotnet add package Mbed.Cloud.SDK
// example: initial setup
npm i mbed-cloud-sdk
# example: initial setup
pip install mbed-cloud-sdk
// example: Initial setup
/*
If using Gradle, you can initialise your project, as follows:
*/
> gradle init --type java-application
/*
Then, add the following dependency to 'build.gradle' file (change 'x', 'y' and 'z' by the appropriate version numbers) :
*/
implementation 'com.arm.mbed.cloud.sdk:mbed-cloud-sdk:x.y.z'
/*
Next time you build your project, the dependencies will be fetched and stored in your package manager cache.
You are then ready to start working with the SDK.
*/

Install the SDK using the package manager.

Configuration

# Example .env file
# Note that the following API key is fake
MBED_CLOUD_SDK_API_KEY=ak_A644VERY4745LONG64RANDOM3254STRINGW555455ITHA564miXTurOFlowercaseANDUPPERCASELETTERSIintersperseDwithNUMBER5 

The SDKs use an API key to access the Pelion Device Management REST API, details on how to create an API Key are available in the Prerequisites section.

The recommended method of configuring the SDK during development is by using a .env file. The file can be located in any accessible directory between your project and the root directory. Note that .env files closer to the working directory (or any variables in the system environment) take priority.

To get started it is only necessary to define the API Key, but the following table describes the full list of configuration options that can be defined:

Environment Variable Type Default Usage
MBED_CLOUD_SDK_API_KEY String N/A API Key used for Authentication.
MBED_CLOUD_SDK_HOST URI Arm's public API The host on which the Pelion Device Management API is available. This is only likely to be needed if you organisation has its own cloud deployment.

For other configuration methods please see the following sections:

Hello World

// example: hello world
using System;
using System.Threading.Tasks;
using Mbed.Cloud.Foundation;

public class HelloWorldExamples
{
    public static void Main()
    {
        var options = new DeviceListOptions
        {
            MaxResults = 10     // Limit to ten devices
        };

        // List the first ten devices on your Pelion Device Management account.
        foreach (var device in new DeviceRepository().List(options))
        {
            Console.WriteLine($"Hello device {device.Name}");
        }
    }
}
// example: hello_world
import { DeviceRepository } from "mbed-cloud-sdk";

const main = async () => {
    // create an instance of a device repository
    const deviceList = new DeviceRepository()
        // List the first 10 devices in your Pelion DM account
        .list({ maxResults: 10 });

    for await (const device of deviceList) {
        console.log(`Hello device ${device.name}`);
    }
};

main();
# example: hello world
from mbed_cloud.foundation import Device

# List the first 10 devices on your Pelion Device Management account.
for device in Device().list(max_results=10):
    print("Hello device %s" % device.name)
// example: hello world
import java.io.IOException;

import com.arm.mbed.cloud.sdk.common.MbedCloudException;
import com.arm.mbed.cloud.sdk.devices.model.DeviceListDao;
import com.arm.mbed.cloud.sdk.devices.model.DeviceListOptions;

public class HelloWorld {

    public static void main(String[] args) {

        try (DeviceListDao dao = new DeviceListDao()) {

            // Listing the first 10 devices on your Pelion Device Management account
            dao.list((new DeviceListOptions()).maxResults(10))
               .forEach(device -> System.out.println("Hello device " + device.getName()));

        } catch (MbedCloudException | IOException exception) {
            exception.printStackTrace();
        }
    }

}

This simple interaction between the SDK and Pelion Device Management shows that everything is set up and working.

Next Steps

The SDKs have several ways to interface with Pelion Device Management and connected devices. The section Interface Overview provides details on how these are organised fit together. However, these resources should help with getting started:

Interface Overview

There are three conceptual interfaces to each SDK, each gives an increasing level of abstraction over the underlying REST API.

Interface Overview

There is also a Legacy interface which combines some of the functionality of the Foundation and Primary interfaces. This interface can be difficult to understand, so it is recommended that the new interfaces are used wherever possible.

Primary

The Primary interface offers the highest level of abstraction but only covers certain aspects of the API. This is focused around the asynchronous device data e.g. subscriptions and resource interactions.

Foundation

The Foundation interface is designed to be simple to understand and use. It is organised around the concept of an Entity, but these are arranged into large conceptual groups known as Categories. The Categories do not have any impact on how the entities are used but merely serve as an organisation structure.

Client

The Client interface is the lowest level and offers direct access to the REST API. It's only recommended for new, complex or highly specific features of the API, when the Primary or Foundation interfaces are not suitable. However, it does provide an easy way to access any Pelion Device Management API endpoint without having to setup the authentication manually.

Legacy

The Legacy interface is arranged around the organisation of Pelion services and it may not be easy to navigate. This interface is in maintenance mode and new REST API endpoints and resource properties will not normally be added to this interface. To each Pelion service, there is a corresponding Module in the SDK:

SDK Interface

An SDK Instance is the recommended way for using the SDK. It provides a few useful tools that will help as the application becomes more complex:

Getting Started Revisited

// example: hello world with sdk instance
using System;
using System.Threading.Tasks;
using Mbed.Cloud;
using Mbed.Cloud.Foundation;

public class HelloWorldSeparateSdkExamples
{
    public static void Main()
    {
        // Create an instance of the Pelion Device Management SDK
        var sdk = new SDK();

        var options = new DeviceListOptions
        {
            MaxResults = 10     // Limit to ten devices
        };

        // List the first ten devices on your Pelion Device Management account
        foreach (var device in sdk.Foundation().DeviceRepository().List(options))
        {
            Console.WriteLine($"Hello device {device.Name}");
        }
    }
}
// example: hello_world_with_sdk_instance
import { SDK } from "mbed-cloud-sdk";

const main = async () => {
    // create an instance of the Pelion Device Management SDK
    const deviceList = new SDK()
        .foundation()
        .deviceRepository()
        // List the first 10 devices in your Pelion DM account
        .list({ maxResults: 10 });

    for await (const device of deviceList) {
        console.log(`Hello device ${device.name}`);
    }
};

main();
# example: hello world with sdk instance
from mbed_cloud import SDK

# Create an instance of the Pelion Device Management SDK
pelion_dm_sdk = SDK()
# List the first 10 devices on your Pelion DM account
for device in pelion_dm_sdk.foundation.device().list(max_results=10):
    print("Hello device %s" % device.name)
// example: hello world with sdk instance
import com.arm.mbed.cloud.Sdk;
import com.arm.mbed.cloud.sdk.common.ConnectionOptions;
import com.arm.mbed.cloud.sdk.common.MbedCloudException;
import com.arm.mbed.cloud.sdk.devices.model.DeviceListOptions;

public class HelloWorldWithSdkInstance {

    public static void main(String[] args) {

        // Create an instance of the Pelion Device Management SDK
        try (Sdk sdk = Sdk.createSdk(ConnectionOptions.newConfiguration())) {

            // Listing the first 10 devices on your Pelion Device Management account
            sdk.foundation().getDeviceListDao().list((new DeviceListOptions()).maxResults(10))
               .forEach(device -> System.out.println("Hello device " + device.getName()));

        } catch (MbedCloudException exception) {
            exception.printStackTrace();
        }

    }

}

This example has the same functionality as the original Hello World example, which accessed a Foundation entity. However, it uses an SDK instance, which is the preferred pattern for more complex applications.

Working with Multiple API Keys

// example: hello world with multiple api keys
using System;
using System.Threading.Tasks;
using Mbed.Cloud;
using Mbed.Cloud.Common;
using Mbed.Cloud.Foundation;

public class MultipleApiKeys
{
    public static void Main()
    {
        // Create instances of the Pelion Device Management SDK for two accounts
        var account_one = new SDK(API_KEY_ONE);
        var account_two = new SDK(API_KEY_TWO);

        var options = new DeviceListOptions
        {
            MaxResults = 10     // Limit to ten devices
        };

        // List the first ten devices on the first account
        foreach (var device in account_one.Foundation().DeviceRepository().List(options))
        {
            Console.WriteLine("Account One device " + device.Name);
        }

        // List the first ten devices on the second account
        foreach (var device in account_two.Foundation().DeviceRepository().List(options))
        {
            Console.WriteLine("Account Two device " + device.Name);
        }
    }
}
// example: hello_world_with_multiple_api_keys
import { SDK } from "mbed-cloud-sdk";

const main = async () => {
    const accountOne = new SDK({ apiKey: process.env.account_one_api_key });
    const deviceList = accountOne
        .foundation()
        .deviceRepository()
        .list();

    for await (const device of deviceList) {
        console.log(`account one device ${device.name}`);
    }

    const accountTwo = new SDK({ apiKey: process.env.account_two_api_key });
    accountTwo
        .foundation()
        .deviceRepository()
        .list();

    for await (const device of deviceList) {
        console.log(`account two device ${device.name}`);
    }
};

main();
# example: hello world with multiple api keys
from mbed_cloud import SDK

# Create instances of the Pelion Device Management SDK for two accounts
account_one = SDK(api_key=ACCOUNT_ONE_API_KEY)
account_two = SDK(api_key=ACCOUNT_TWO_API_KEY)

# List the first 10 devices on the first account
for device in account_one.foundation.device().list(max_results=10):
    print("Account One device %s" % device.name)

# List the first 10 devices on the second account
for device in account_two.foundation.device().list(max_results=10):
    print("Account Two device %s" % device.name)
// example: hello world with multiple API keys
import com.arm.mbed.cloud.Sdk;
import com.arm.mbed.cloud.sdk.common.ConnectionOptions;
import com.arm.mbed.cloud.sdk.common.MbedCloudException;
import com.arm.mbed.cloud.sdk.devices.model.DeviceListOptions;

public class HelloWorldWithMultipleSdkInstances {

    public static void main(String[] args) {
        // Create instances of the Pelion Device Management SDK for two accounts
        try (Sdk accountOne = Sdk.createSdk(ConnectionOptions.newConfiguration(ACCOUNT_ONE_API_KEY));
             Sdk accountTwo = Sdk.createSdk(ConnectionOptions.newConfiguration(ACCOUNT_TWO_API_KEY))) {
            // Listing the first 10 devices on the first account
            accountOne.foundation().getDeviceListDao().list((new DeviceListOptions()).maxResults(10))
                      .forEach(device -> System.out.println("Hello device " + device.getName()));
            // Listing the first 10 devices on the second account
            accountTwo.foundation().getDeviceListDao().list((new DeviceListOptions()).maxResults(10))
                      .forEach(device -> System.out.println("Hello device " + device.getName()));

        } catch (MbedCloudException exception) {
            exception.printStackTrace();
        }
    }

}

When working with a single API Key it is recommended that the SDK configuration is defined globally using environment variables (or during development via a .env file) as described in the Configuration section.

However, it is possible to work with multiple API Keys simultaneously by using different SDK instances, where each SDK instance is provided with the configuration at runtime. It is still recommended that the configuration is stored in environment variables (as shown in the examples), rather than being included directly in the source code.

Foundation Interface

This guide provides some examples of how to work with entities for common operations. However, each entity will have different methods and properties depending on the underlying REST API endpoints and resource contents. This will be visible in the associated language reference documentation. The following sections should be of help in discovering available functionality and uses cases:

Creating an Entity

// example: create an entity
var newUser = new User
{
    Email = "csharp.sdk.user@arm.com"
};

await sdk
    .Foundation()
    .UserRepository()
    .Create(newUser);
// example: create_an_entity
const newUser: User = {
    email: "javascript.sdk.user@arm.com",
};
await sdk.foundation().userRepository().create(newUser);
# example: create an entity
new_user = pelion_dm_sdk.foundation.user(
    email="python.sdk.user@arm.com",
)
new_user.create()
// example: create an entity
User newUser = new User();
newUser.setEmail("java.sdk.user@arm.com");
sdk.foundation().getUserDao().create(newUser);

The SDK allows resources to be created in Pelion Device Management, to do this the create method of the Entity should be called.

Reading an Entity

// example: read an entity
var userOne = await sdk
                    .Foundation()
                    .UserRepository()
                    .Read(userId);
Console.WriteLine($"User email address: {userOne.Email}");
// example: read_an_entity
const userOne = await sdk.foundation().userRepository().read(newUser.id);
console.log(`User email address: ${userOne.email}`);
# example: read an entity
user_one = pelion_dm_sdk.foundation.user(id=user_id).read()
print("User email address: %s" % user_one.email)
// example: read an entity
User userOne = sdk.foundation().getUserDao().read(userId);
System.out.println("User email address: " + userOne.getEmail());

The SDK allows individual resources to be read from Pelion Device Management, to do this the read method of the Entity should be called.

Updating an Entity

// example: update an entity
var userTwo = await sdk
                    .Foundation()
                    .UserRepository()
                    .Read(userId);

userTwo.FullName = "CSharp SDK User";

await sdk
    .Foundation()
    .UserRepository()
    .Update(userTwo.Id, userTwo);
// example: update_an_entity
const userTwo = await sdk.foundation().userRepository().read(newUser.id);
userTwo.fullName = "Javascript SDK User";
await sdk.foundation().userRepository().update(userTwo, userTwo.id);
# example: update an entity
user_two = pelion_dm_sdk.foundation.user(id=user_id).read()
user_two.full_name = "Python SDK User"
user_two.update()
// example: update an entity
User userTwo = sdk.foundation().getUserDao().read(userId);
userTwo.setFullName("Java SDK User");
sdk.foundation().getUserDao().update(userTwo);

The SDK allows individual resources to be updated in Pelion Device Management, to do this the update method of the Entity should be called.

Deleting an Entity

// example: delete an entity
var userThree = await sdk
                    .Foundation()
                    .UserRepository()
                    .Read(userId);

await sdk
    .Foundation()
    .UserRepository()
    .Delete(userThree.Id);
// example: delete_an_entity
const userThree = await sdk.foundation().userRepository().read(newUser.id);
await sdk.foundation().userRepository().delete(userThree.id);
# example: delete an entity
pelion_dm_sdk.foundation.user(id=user_id).delete()
// example: delete an entity
User userThree = sdk.foundation().getUserDao().read(userId);

sdk.foundation().getUserDao().delete(userThree);

The SDK allows individual resources to be deleted from Pelion Device Management, to do this the delete method of the Entity should be called.

Iterating over Entities

// example: list entities
var options = new UserListOptions
{
    Order = "ASC",
    PageSize = 5,
    MaxResults = 10,
    Include = "total_count"
};

var userList = sdk
                .Foundation()
                .UserRepository()
                .List(options);

foreach (var user in userList)
{
    Console.WriteLine($"{user.FullName}: ({user.Id}): {user.Email}");
}
// example: list_entities
const paginator = sdk
    .foundation()
    .userRepository()
    .list({
        maxResults: 10,
        pageSize: 5,
        order: "ASC",
        include: "total_count",
    });

for await (const user of paginator) {
    console.log(`${user.fullName} (${user.id}): ${user.email}`);
}

console.log(`Total count: ${paginator.totalCount}`);
# example: list entities
paginator = pelion_dm_sdk.foundation.user().list(
    order="ASC",
    page_size=5,
    max_results=10,
    include="total_count")

for user in paginator:
    print("%s (%s): %s" % (user.full_name, user.id, user.email))

print("Total Count: %d" % paginator.count())
// example: list entities
Paginator<User> paginator = sdk.foundation().getUserListDao()
                               .list(new UserListOptions().maxResults(10).pageSize(5).order(Order.ASC)
                                                          .includeTotalCount());

paginator.forEach(u -> System.out.println(user.getFullName() + " (" + user.getId() + "): " + u.getEmail()));
System.out.println("Total count: " + paginator.count());

Each SDK provides an iterator for list endpoints in the REST API. This avoids the need to store all the entities and instead retrieves them a page at a time from the REST API. This behaviour is transparent to the user of the SDK but can be controlled with the following parameters:

Paginator

// example: read first entity in list
var firstUserInList = sdk
                        .Foundation()
                        .UserRepository()
                        .List()
                        .FirstOrDefault();

Console.WriteLine($"User email address: {firstUserInList.Email}");
// example: read_first_entity_in_list
const firstUserInList = await sdk
    .foundation()
    .userRepository()
    .list()
    .first();

console.log(`User email address: ${firstUserInList.email}`);
# example: read first entity in list
first_user_in_list = pelion_dm_sdk.foundation.user().list().first()
print("User email address: %s" % first_user_in_list.email)
// example: read first entity in list
User firstUserInList = sdk.foundation().getUserListDao().list().first();
System.out.println("User email address: " + firstUserInList.getEmail());

The iteration mechanism is referred to as a Paginator (due to its paging behaviour). In addition to providing the iterator interface, Paginators also have additional utility methods. These vary between languages, please consult the appropriate language reference documentation for full details:

Filtering Entities

// example: list entities with filters
var userOptions = new UserListOptions()
    .EmailEqualTo("mr.test@mydomain.com")
    .StatusIn(UserStatus.ACTIVE, UserStatus.ENROLLING);

userList = sdk
            .Foundation()
            .UserRepository()
            .List(userOptions);

foreach (var user in userList)
{
    Console.WriteLine($"{user.FullName}: ({user.Id}): {user.Email}");
}
// example: list_entities_with_filters
const paginator = sdk
    .foundation()
    .userRepository()
    .list({
        filter: {
            email: "javascript.sdk.user@arm.com",
            status: {
                in: [
                    "ACTIVE",
                    "ENROLLING",
                ]
            }
        },
    });

for await (const user of paginator) {
    console.log(`${user.fullName} (${user.id}): ${user.email}`);
}

console.log(`Total count: ${paginator.totalCount}`);
# example: list entities with filters
from mbed_cloud import ApiFilter
from mbed_cloud.foundation.enums import UserStatusEnum

api_filter = ApiFilter()
api_filter.add_filter("email", "eq", "python.sdk.user@arm.com")
api_filter.add_filter("status", "in", [UserStatusEnum.ACTIVE, UserStatusEnum.ENROLLING])

for user in pelion_dm_sdk.foundation.user().list(filter=api_filter):
    print("%s (%s): %s" % (user.full_name, user.id, user.email))
// example: list entities with filters
sdk.foundation().getUserListDao()
   .list(new UserListOptions().equalToEmail("java.sdk.user@arm.com")
                              .inStatuses(Arrays.asList(UserStatus.ACTIVE, UserStatus.ENROLLING)))
   .forEach(u -> System.out.println(user.getFullName() + " (" + user.getId() + "): " + u.getEmail()));

Most endpoints which list resources in the Pelion Device Management REST API also provide a filter mechanism to reduce the number of resources returned and find resources of interest. The available filters for each list endpoint will either documented in the language reference documentation or programmatically described in the SDK itself.

Filters can be combined (using an implicit AND) to restrict which resources are returned, as is shown in the examples.

Client Interface

// example: custom api call
var client = new Client(new Config());
var res = await client.CallApi<ResponsePage<User>>(method: HttpMethods.GET, path: "/v3/users", queryParams: new Dictionary<string, object> { { "limit", 2 } });
// example: custom api call
const sdk = new SDK();
const users = await sdk.client.CallApi({ url: "/v3/users", method: "GET", query: { limit: 2 } });
# example: custom api call
from mbed_cloud import SDK
from mbed_cloud.foundation import User
response = SDK().client.call_api('get', '/v3/users', query_params={'limit': 2})
# response object from the`requests` library
for user_data in response.json()['data']:
    user = User().from_api(**user_data)
// example: custom api call
/**
 * Definition of the REST endpoint.
 * <p>
 * See the documentation from <a href="https://square.github.io/retrofit/">Retrofit</a> to see how to defined a
 * service.
 */
private interface PelionApi {
    @GET("v3/users")
    Call<UserListResponse> listAllUsers(@retrofit2.http.Query("limit") Integer limit);
}

/**
 * Definition of the response object.
 */
private static class UserListResponse {
    List<User> data;

    public List<User> getData() {
        return data;
    }

    @SuppressWarnings("unused")
    public void setData(List<User> data) {
        this.data = data;
    }

}

    // Create a generic client
    GenericClient client = GenericClient.newClient(Configuration.get());
    // Define how to generate the request based on a set of parameters
    CloudRequest<UserListResponse, PelionApi> requestDefinition = new CloudRequest<UserListResponse, PelionApi>() {

        @Override
        public com.arm.mbed.cloud.sdk.common.CloudRequest.CloudCall<UserListResponse>
               defineCall(PelionApi service, Object... parameters) throws MbedCloudException {

            return new CloudCall<GenericClientExamples.UserListResponse>() {

                @Override
                public Call<UserListResponse> call() {
                    return service.listAllUsers((Integer) parameters[0]);
                }

            };
        }

    };
        // Make the call with the following set of parameters. here, limit = 2.
        UserListResponse response = client.callApi(requestDefinition, Integer.valueOf(2));
        for (User user : response.getData()) {
            // Do something with users
            System.out.println(user);
        }

New or highly specific features of the API may be best served using direct API calls. To allow development to continue within the SDK and provide a consistent interface, we present these custom API call methods.

Of course, do let us know if there is an aspect of the API you would like us to cover!

Legacy Interface

In order to perform an action using the Legacy Interface, the API within which the functionality resides needs to be identified.

Each API is represented by a module in the SDK, the methods in the module normally correspond to direct calls to the REST API. The Legacy Interface uses a common model object which combines the request and response objects (as they are defined in the REST API) into a single object.

Reading a Resource

// example: legacy_get_resource
using Mbed.Cloud.Common;
using MbedCloudSDK.Billing.Api;
var billingApi = new BillingApi(new Config());
Console.WriteLine($"Quota remaining: {billingApi.GetQuotaRemaining()}");
// example: legacy_get_resource
import { BillingApi } from "mbed-cloud-sdk";
const billingApi = new BillingApi();
console.log(`Quota remaining: ${await billingApi.getQuotaRemaining()}`);
# example: legacy get resource
from mbed_cloud import BillingAPI

billing_api = BillingAPI()
print("Quota remaining: %s" % billing_api.get_quota_remaining())
// example: legacy get resource
try (Billing billingApi = new Billing(Configuration.get())) {
    log("Quota remaining: " + billingApi.getQuotaRemaining());

} catch (MbedCloudException exception) {
    // TODO do something with the exception
    exception.printStackTrace();
    // Fails if an exception happened
}

The Legacy Interface allows individual resources to be read from the REST API.

Listing Resources

// example: legacy_listing_resources
using Mbed.Cloud.Common;
using MbedCloudSDK.Billing.Api;
var billingApi = new BillingApi(new Config());
foreach (var quotaHistory in billingApi.GetQuotaHistory())
{
    Console.WriteLine($"Quota change reason: {quotaHistory.Reason}, delta: {quotaHistory.Delta}");
}
// example: legacy_listing_resources
import { BillingApi } from "mbed-cloud-sdk";
const billingApi = new BillingApi();
billingApi.getQuotaHistory()
    .then(data => {
        data.data.forEach(quotaHistory => {
            console.log(`Quota change reason: ${quotaHistory.reason}, delta: ${quotaHistory.delta}`);
        });
    });
# example: legacy listing resources
from mbed_cloud import BillingAPI

billing_api = BillingAPI()
for quota_history in billing_api.get_quota_history():
    print("Quota change reason: %s, delta: %s" % (quota_history.reason, quota_history.delta))
// example: legacy listing resources
try (Billing billingApi = new Billing(Configuration.get())) {
    billingApi.getAllQuotaHistory(null)
              .forEach(q -> log("Quota change reason: " + q.getReason() + ", delta: " + q.getDelta()));

} catch (MbedCloudException exception) {
    // TODO do something with the exception
    exception.printStackTrace();
    // Fails if an exception happened
}

When a REST API list endpoint is called the Legacy Interface returns a Paginator which allows the resources to be iterated over in a similar way to the Foundation Interface.

Use Cases

Managing Accounts

// example: creating and managing a subtenant account
myAccount = await accountRepo.Create(new Account
{
    DisplayName = "new test account",
    Aliases = new List<string>() { "alex_test_account" },
    EndMarket = "IOT",
    AdminFullName = "Alex Logan",
    AdminEmail = "alexadmin@admin.com",
});
var userRepo = new SubtenantUserRepository();

// get first subtenant user acociated with the account
var firstUser = accountRepo.Users(myAccount.Id).FirstOrDefault();

var originalPhoneNumber = firstUser.PhoneNumber;

var newPhoneNumber = originalPhoneNumber + "00";

// update the user's phone number
firstUser.PhoneNumber = newPhoneNumber;
await userRepo.Update(myAccount.Id, firstUser.Id, firstUser);


// change it back to the original
firstUser.PhoneNumber = originalPhoneNumber;
await userRepo.Update(myAccount.Id, firstUser.Id, firstUser);

// example: creating and managing a subtenant account
const newAccount: Account = {
    displayName: "new test account",
    aliases: [
        "alex_test_account"
    ],
    endMarket: "IOT",
    // Admin user details
    adminFullName: "Alex Logan",
    adminEmail: "alexadmin@admin.com",
};

myAccount = await accountContext.create(newAccount);
const subtenantUserContext = new SubtenantUserRepository();
// Populate the new user details
const user: SubtenantUser = {
    // Link this user to the account
    accountId: myAccount.id,
    // User details
    fullName: "tommi the wombat",
    username: "tommi_wombat",
    phoneNumber: "0800001066",
    email: "tommi_the_wombat@email.com",
};

// create the new user
await subtenantUserContext.create(user, myAccount.id);

# example: creating and managing a subtenant account
from mbed_cloud.foundation import Account, SubtenantUser

# Populate the new account details
new_subtenant = Account(
    display_name='sdk test bob',
    aliases=['sdk_test_bob_' + random_string()],
    end_market='connected warrens',
    # Admin user details
    admin_full_name='bob the wombat',
    admin_email='bob@example.com',
)
# Create the new account
new_subtenant.create()
account_id = new_subtenant.id
print("This is my new Account ID: %s" % account_id)


# Populate the new user details
new_user = SubtenantUser(
    # Link this user to the account
    account_id=account_id,
    # User details
    username='JaneDoeSDK',
    full_name='Jane Doe',
    email='jane.doe@example.com',
    phone_number='1800966228',
)
# Create the new user
new_user.create()

// example: creating and managing a subtenant account
try (Sdk sdk = Sdk.createSdk(Configuration.get()); AccountDao myAccountDao = sdk.foundation().getAccountDao();
     SubtenantUserDao userDao = sdk.foundation().getSubtenantUserDao();) {
    // Fetch my account
    myAccountDao.me();
    // Create a new User
    SubtenantUser user = new SubtenantUser();
    user.setAccountId(myAccountDao.getId());
    user.setFullName("tommi the wombat");
    user.setEmail("tommi_the_wombat@email.com");
    user.setUsername("tommi_wombat");
    user.setPhoneNumber("0800001066");
    userDao.create(user);
    // Find this added user in my account user list.
    String createdId = userDao.getId();
    // Fetch latest details of the current sub-tenant user.
    userDao.read();
    // Fetching a user from the list of account users
    SubtenantUser correspondingUser = StreamSupport.stream(myAccountDao.allUsers(null).spliterator(), false)
                                                   .filter(u -> u.getId().equals(createdId)).findFirst().get();
    // Delete the created user.
    userDao.delete();

} catch (MbedCloudException | IOException exception) {
    // TODO do something with the exception
    exception.printStackTrace();
}

This is a more complex example demonstrating how to use the interfaces to create and manage a subtenant account.

Renewing a certificate

// example: certificate renew
var myConfig = new CertificateIssuerConfigRepository().List().All().FirstOrDefault(c => c.Reference == "LWM2M");

var connectedDevices = new DeviceRepository()
    .List()
    .All()
    .Where(d => d.State == DeviceState.REGISTERED)
    .ToList();


foreach (var device in connectedDevices)
{
    await new DeviceRepository().RenewCertificate(myConfig.Reference, device.Id);
}
// example: certificate renew
const certificateIssuerConfigContext = new CertificateIssuerConfigRepository();
const myConfig = (await certificateIssuerConfigContext.list().all()).find(c => c.reference === "LWM2M");

const deviceContext = new DeviceRepository();
const connectedDevices = (await deviceContext.list().all()).filter(device => device.state === "registered");

for (const device of connectedDevices) {
    await deviceContext.renewCertificate(myConfig.reference, device.id);
}
# example: certificate renew

# Find all certificate issuers that may be in use
certificate_references = []
for certificate_issuer_config in CertificateIssuerConfig().list():
    certificate_references.append(certificate_issuer_config.certificate_reference)

# List all devices
for device in Device().list():
    # A certificate can only be renewed on a registered device
    if device.state == DeviceStateEnum.REGISTERED:
        # It is not possible to determine which certificate issuer has been used on a
        # device so try them in turn.
        for certificate_reference in certificate_references:
            try:
                # If the wrong certificate issuer is selected then the renew will fail
                device.renew_certificate(certificate_reference)
            except ApiErrorResponse:
                print("Certificate '%s' could not be renewed on device '%s'" % (
                    certificate_reference, device.name))
            else:
                print("Certificate '%s' was renewed on device '%s'" % (
                    certificate_reference, device.name))
// example: certificate renew
try (Sdk sdk = Sdk.createSdk(Configuration.get()); DeviceDao deviceDao = sdk.foundation().getDeviceDao()) {
    // Find the certificate issuers configuration in use. In this case, it is known that the reference is
    // "LWM2M".
    CertificateIssuerConfig myConfig = StreamSupport.stream(sdk.foundation().getCertificateIssuerConfigListDao()
                                                               .getPaginator().spliterator(),
                                                            false)
                                                    .filter(c -> c.getReference().equals("LWM2M")).findFirst()
                                                    .get();
    // Renew the certificate of all connected devices
    StreamSupport.stream(sdk.foundation().getDeviceListDao().paginator().spliterator(), false)
                 .filter(d -> d.getState() == DeviceState.REGISTERED).forEach(d -> {
                     // Configure the DAO with the model of interest
                     try {
                         deviceDao.setModel(d);
                         deviceDao.renewCertificate(myConfig.getReference());
                         log(myConfig + " was renewed on " + d);
                     } catch (@SuppressWarnings("unused") MbedCloudException exception) {
                         // TODO do something with the exception
                         log(myConfig + " could not be renewed on " + d);
                     }

                 });

} catch (MbedCloudException | IOException exception) {
    // TODO do something with the exception
    exception.printStackTrace();
}

This example shows how to renew the certificate on a device.

Enrolling a device

// example: device enrollment single
var enrollmentRepo = new DeviceEnrollmentRepository();
var enrollment = new DeviceEnrollment
{
    EnrollmentIdentity = "A-4E:63:2D:AE:14:BC:D1:09:77:21:95:44:ED:34:06:57:1E:03:B1:EF:0E:F2:59:44:71:93:23:22:15:43:23:12",
};
await enrollmentRepo.Create(enrollment);
// example: device enrollment single
const enrollmentContext = new DeviceEnrollmentRepository();
const enrollment: DeviceEnrollment = {
    enrollmentIdentity: "A-4E:63:2D:AE:14:BC:D1:09:77:21:95:44:ED:34:06:57:1E:03:B1:EF:0E:F2:59:44:71:93:23:22:15:43:23:12",
};
await enrollmentContext.create(enrollment);
# example: device enrollment single

# Enroll a single device using the enrollment ID for the device
device_enrollment = DeviceEnrollment(
    enrollment_identity = "A-4E:63:2D:AE:14:BC:D1:09:77:21:95:44:ED:34:06:57:1E:03:B1:EF:0E:F2:59:44:71:93:23:22:15:43:23:12")

device_enrollment.create()

There are two different ways to enroll a device.

Firstly, you can enroll one device at a time using the device enrollment entity.

// example: device enrollment bulk
var bulkRepo = new DeviceEnrollmentBulkCreateRepository();

// use System.IO file open
var bulk = default(DeviceEnrollmentBulkCreate);
using (var file = File.Open(pathToCsv, FileMode.Open))
{
    bulk = await bulkRepo.Create(file);
}


bulk = await bulkRepo.Read(bulk.Id);
// example: device enrollment bulk
const bulkCreateContext = new DeviceEnrollmentBulkCreateRepository();
// uses fs readStream so this is a node only example.
const csv = createReadStream(pathToCsv);
let createTask = await bulkCreateContext.create(csv);

// call get to see current state of bulk enrollment
createTask = await bulkCreateContext.read(createTask.id);


const reportFile = await bulkCreateContext.downloadFullReportFile(createTask) as ReadStream;
// stream report file into string and print it
printFile(reportFile);

const errorFile = await bulkCreateContext.downloadErrorsReportFile(createTask) as ReadStream;
printFile(errorFile);

# example: device enrollment bulk
with open("tests/fixtures/bulk_device_enrollment.csv", "rb") as csv_file_handle:
    bulk_device_enrollment = DeviceEnrollmentBulkCreate().create(csv_file_handle)

while bulk_device_enrollment.status != DeviceEnrollmentBulkCreateStatusEnum.COMPLETED:
    time.sleep(1)
    bulk_device_enrollment.get()

print(bulk_device_enrollment.download_full_report_file().read())
print(bulk_device_enrollment.download_errors_report_file().read())
// example: device enrollment bulk
try (Sdk sdk = Sdk.createSdk(Configuration.get());
     DeviceEnrollmentBulkCreateDao enrolmentDao = sdk.foundation().getDeviceEnrollmentBulkCreateDao()) {
    // file is a csv file containing all the devices which need to be enrolled. See test.csv in the /resources
    // folder as example.
    enrolmentDao.create(new DataFile(file));
    // read current state of bulk enrollment
    enrolmentDao.read();
    // Wait until the report is ready
    // FIXME this is just a cruddy example of waiting for the bulk operation to complete. Better handling should
    // be performed in production application.
    while (enrolmentDao.getModel().getStatus() != DeviceEnrollmentBulkCreateStatus.COMPLETED) {
        Thread.sleep(1000);
        enrolmentDao.read();
    }
    // Download the enrolment report files
    FileDownload report = enrolmentDao.downloadFullReportFile((String) null);
    log("report", report);
    FileDownload errorReport = enrolmentDao.downloadErrorsReportFile((String) null);
    log("errorReport", errorReport);

} catch (MbedCloudException | InterruptedException exception) {
    // TODO do something with the exception
    exception.printStackTrace();
}

Alternatively, you can enroll many devices at the same time using the device enrollment bulk create` entity.

Launching a firmware update campaign

// example: firmware_update_campaign_launch
var updateCampaignRepo = sdk.Foundation().UpdateCampaignRepository();
var campaign = await updateCampaignRepo.Create(new UpdateCampaign
{
    Name = $"campaign - {DateTime.Now}",
    Description = "Update campaign for prior 2019 devices",
    RootManifestId = firmwareManifest.Id,
    DeviceFilterHelper = new DeviceListOptions().CreatedAtLessThan(new DateTime(2019, 1, 1)).Filter,
});

Console.WriteLine((await updateCampaignRepo.Read(campaign.Id)).Phase);

await updateCampaignRepo.Start(campaign.Id);

Console.WriteLine((await updateCampaignRepo.Read(campaign.Id)).Phase);

foreach (var metadata in updateCampaignRepo.DeviceMetadata(campaign.Id))
{
    Console.WriteLine(metadata);
}
// example: firmware_update_campaign_launch
const updateCampaignRepo = sdk.foundation().updateCampaignRepository();
const filter: DeviceFilter = {
    createdAt: {
        lte: [
            new Date(2019, 0, 1)
        ],
    }
};
const campaign = await updateCampaignRepo.create({
    name: `campaign - ${new Date()}`,
    description: "Update campaign for prior 2019 devices",
    rootManifestId: firmwareManifest.id,
    deviceFilter: encodeFilter(filter),
});

console.log((await updateCampaignRepo.read(campaign.id)).phase);

await updateCampaignRepo.start(campaign.id);

console.log((await updateCampaignRepo.read(campaign.id)).phase);

for await (const metadata of updateCampaignRepo.deviceMetadata(campaign.id)) {
    console.log(metadata);
}
# example: firmware update campaign launch
from datetime import datetime
from pprint import pprint
from mbed_cloud import SDK
from mbed_cloud import ApiFilter

pelion_dm_sdk = SDK()
new_campaign = pelion_dm_sdk.foundation.update_campaign(
    root_manifest_id=my_manifest_id,
    name="campaign - " + str(datetime.now()),
    description="Update campaign for prior 2019 devices"

)

# Create a filter for all devices created before the 1st of January 2019 so that these devices will have their
# firmware replaced by the one defined in the manifest.
api_filter = ApiFilter()
api_filter.add_filter("created_at", "lte", datetime(2019, 1, 1))
new_campaign.device_filter_helper = api_filter

# Create the campaign
new_campaign.create()

# Determine the phase of the campaign
print("Campaign Phase:", new_campaign.phase)

# Start the campaign
new_campaign.start()

# Determine the phase of the campaign
new_campaign.read()
print("Campaign Phase:", new_campaign.phase)

# Print all device metadata related to this campaign
for campaign_device_metadata in new_campaign.device_metadata():
    pprint(campaign_device_metadata.to_dict())

// example: firmware update campaign launch
UpdateCampaignDao myCampaignDao = sdk.foundation().getUpdateCampaignDao();
// Define an update campaign
UpdateCampaign newCampaign = new UpdateCampaign();
newCampaign.setName("campaign - " + (new Date().toString()));
newCampaign.setDescription("Update campaign for prior 2019 devices");
newCampaign.setRootManifestId(myManifestId);
// All devices created before the 1st of January 2019 will have their firmware replaced by the one defined
// in the manifest
newCampaign.setDeviceFiltersHelper(new DeviceListOptions().lessThanCreatedAt(new GregorianCalendar(2019, 0,
                                                                                                   1).getTime())
                                                          .getFilter());
// Create the campaign
myCampaignDao.create(newCampaign);
// Determine the phase of the campaign
System.out.println(myCampaignDao.read().getPhase());
// Start the campaign
myCampaignDao.start();
// Determine the phase of the campaign
System.out.println(myCampaignDao.read().getPhase());
// Print all device metadata related to this campaign
myCampaignDao.allDeviceMetadata(null).all().forEach(System.out::println);

The firmware of devices in the field can be automatically and securely updated by launching an update campaign. Provided that a firmware image and a manifest have been uploaded to Pelion Device Management, such a campaign can be created and then started. It is also possible to stop or archive campaigns in progress if need be.

Setting and Getting Device Resource Values

// example: get and set a resource value
using Mbed.Cloud;
using Mbed.Cloud.Common;
using Mbed.Cloud.Foundation;
using Mbed.Cloud.Foundation.Enums;
using MbedCloudSDK.Connect.Api;

// Use the Foundation interface to find a connected device.
var device = sdk
                .Foundation()
                .DeviceRepository()
                .List(new DeviceListOptions().StateEqualTo(DeviceState.REGISTERED))
                .FirstOrDefault();

// Use the Legacy interface for find resources
var config = new Config
{
    AutostartNotifications = true,
};

using (var connect = new ConnectApi(config))
{
    // Find an observable resource
    var resource = connect
                        .ListResources(device.Id)
                        .FirstOrDefault(r => r.Observable == true);

    // Set a resource value
    connect.SetResourceValue(resource.DeviceId, resource.Path, "12");

    // Get a resource value
    var value = connect.GetResourceValue(resource.DeviceId, resource.Path);

    Console.WriteLine($"Device {device.Id}, path {resource.Path}, current value: {value}");
}
// example: get and set a resource value
import { ConnectApi, SDK } from "mbed-cloud-sdk";

// Use the Foundation interface to find a connected device.
const device = await sdk.foundation().deviceRepository().list({
    filter: {
        state: "registered",
    }
}).first();

// Use the Legacy interface for find resources
const connectApi = new ConnectApi({
    autostartNotifications: true,
});

// Find an observable resource
const resource = (await connectApi.listResources(device.id))
    .filter(r => r.observable).pop();

// Set a resource value
await connectApi.setResourceValue(device.id, resource.path, "12");

// Get a resource value
const value = await connectApi.getResourceValue(device.id, resource.path);
console.log(`Device ${device.id}, path ${resource.path}, current value: ${value}`);

await connectApi.stopNotifications();
# example: get and set a resource value
from mbed_cloud.foundation import Device
from mbed_cloud import ApiFilter
from mbed_cloud.foundation.enums import DeviceStateEnum
from mbed_cloud import ConnectAPI

# Use the Foundation interface to find a registered device.
api_filter = ApiFilter()
api_filter.add_filter("state", "eq", DeviceStateEnum.REGISTERED)
device = Device().list(max_results=2, filter=api_filter).next()

# Use the Legacy interface to find resources
connect_api = ConnectAPI()

# Find an observable resource
for resource in connect_api.list_resources(device.id):
    if resource.observable:
        break

# Set a resource value
connect_api.set_resource_value(device.id, resource.path, "12")

# Get a resource value
value = connect_api.get_resource_value(device.id, resource.path)
print("Device %s, path %s, current value: %s" %(device.id, resource.path, value))
// example: get and set a resource value
try (Sdk sdk = Sdk.createSdk(Configuration.get()); DeviceListDao dao = sdk.foundation().getDeviceListDao()) {
    // Use the Foundation interface to find a device.
    Paginator<Device> deviceIterator = dao.list(new DeviceListOptions().equalToState(DeviceState.REGISTERED)
                                                                       .maxResults(1));
    Device device = deviceIterator.first();
    // Find an observable resource
    List<Resource> observableResources = sdk.lowLevelRest().getConnectModule().listObservableResources(device);
    Resource resource = observableResources.get(0);
    ResourceDao resourceDao = sdk.resource(resource);
    // Set a resource value
    resourceDao.update("12", ResourceValueType.STRING, new TimePeriod(10));
    // Get a resource value
    value = resourceDao.read(new TimePeriod(10));
    System.out.println("Device " + device.getId() + ", path " + resource.getPath() + ", current value: "
                       + value);
    resourceDao.close();
} catch (Exception e) {
    e.printStackTrace();
}

Interactions with device resource values in the REST API are asynchronous. However, the SDKs provide a simplified way of both setting and getting resource values without worrying about the underlying communication system. This example shows a resource value being set and then the updated value being read back.

Behind the scenes the SDK will handle the asynchronous behaviour of the REST API, which although specific the implementation in the API normally involves creating a separate thread to handle the asynchronous data from the REST API.

Subscribing to Device Resource Values

// example: subscribe to resource values
using Mbed.Cloud.Common;
using MbedCloudSDK.Connect.Api;

var config = new Config
{
    AutostartNotifications = true,
};

using (var connect = new ConnectApi(config))
{
    var observer = await connect.Subscribe.ResourceValuesAsync("*");

    while(true) {
        Console.WriteLine(await observer.NextAsync());
    }
}
// example: subscribe to resource values
import { ConnectApi } from "mbed-cloud-sdk";

const connect = new ConnectApi();

const observer = connect.subscribe.resourceValues({
    deviceId: "*",
});

while (true) {
    console.log(await observer.once());
}
# example: subscribe to resource values
from mbed_cloud import ConnectAPI

# Create an instance of the Connect API
connect_api = ConnectAPI()

# Configure a subscription to receive resource value changes on all devices
channel = connect_api.subscribe.channels.ResourceValues(device_id="*")

# Contact Pelion Device Management to actually make the configured subscription
observer = connect_api.subscribe(channel)

# Print the subscription notifications received
while True:
    print(observer.next().block())

// example: subscribe to resource values
try (Sdk sdk = Sdk.createSdk(Configuration.get())) {
    // Configure a subscription to receive resource value changes on all devices.
    // For more information about backpressure strategies, please have a look at related documentation:
    // https://github.com/ReactiveX/RxJava/wiki/Backpressure
    // For more information about First Value strategies, have a look at
    // com.arm.mbed.cloud.sdk.subscribe.model.FirstValue
    ResourceValueObserver observer = sdk.subscribe(SubscriptionFilterOptions.newFilter().likeDevice("%"),
                                                   BackpressureStrategy.BUFFER, FirstValue.ON_VALUE_UPDATE);
    // Print the subscription notifications received
    observer.flow().subscribe(System.out::println);
} catch (Exception e) {
    e.printStackTrace();
}

It is possible to subscribe to device resource value changes, receiving updates whenever a change to value occurs. This introduces the concept of observers, which allows applications to listen to changes and react accordingly when changes occur. It is also possible to block on the value changing, as in this example, although this may not be so useful in real situations.

The SDK abstracts the underlying REST API concepts of Subscriptions and Pre-Subscriptions to prevent a simple interface. However, this can result in a multitude of HTTP requests. Please see Advanced Usage: Scaling for more information.

Advanced Usage

Scaling

The SDK supports receiving resource values from a large number of devices via the subscription model. These are our recommendations on how to use the Pelion Device Management SDK at this scale.

Other considerations are those of load and robustness.

Production Deployments

In production deployments it is recommended that environment variables are used to configure the SDK. These can normally be stored in a secure way within the platform itself.

The configuration options are defined in the Configuration section and have the same name regardless of whether they are defined in environment variables or in a .env file.

On-Premise Deployments

MBED_CLOUD_SDK_API_KEY=ak_A644VERY4745LONG64RANDOM3254STRINGW555455ITHA564miXTurOFlowercaseANDUPPERCASELETTERSIintersperseDwithNUMBER5
MBED_CLOUD_SDK_HOST==https://api-pelion-device-management.example.com

The SDKs will use the public Pelion Device Management service by default, so it is not normally necessary to define the host in the configuration. If a On_premise deployment is being used then the host will need to be configured, this should either be via an environment variable or using .env file during development.

Appendix: Known Limitations

This appendix includes known limitations of Pelion Device Management or the SDKs.

Appendix: Subscriptions and Pre-Subscriptions

The SDK abstracts the subscriptions and pre-subscription concepts used by the API. The following
background information on how the API works may be helpful:

The default behaviour of the SDK is to expose behaviour which makes sense to the client and hides the differences between subscriptions and pre-subscriptions. This means that using the default SDK behaviour the client will receive value updates in the following cases:

However, there is an overhead which becomes significant when large numbers of devices are used as the SDK makes multiple calls to the REST API to create both subscriptions and pre-subscriptions.

Setting OnRegistration as the value of the FirstValueEnum parameter avoids this overhead but means that there will be a delay before resource value updates are received by the client for connected devices. This is because devices must re-register before the configured subscription becomes active (re-registering is a periodic occurrence the frequency of which is application/context specific but is typically once every 10 minutes). Using this setting the client will receive value updates in the following cases:

Appendix: Foundation Entities

This appendix lists all the Foundation interface entities, how they map to REST API calls and any differences in naming or usage.

Accounts: Account

The following REST API fields are not used by the SDK:

Entity Method REST API Mapping Notes
api_keys GET: /v3/accounts/{account_id}/api-keys This lists the api keys of the subtenant account.
create POST: /v3/accounts
dark_theme_branding_colors GET: /v3/accounts/{account_id}/branding-colors/dark This lists the dark theme banding colors of the subtenant account.
dark_theme_branding_images GET: /v3/accounts/{account_id}/branding-images/dark This lists the dark theme banding images of the subtenant account.
light_theme_branding_colors GET: /v3/accounts/{account_id}/branding-colors/light This lists the light theme banding colors of the subtenant account.
light_theme_branding_images GET: /v3/accounts/{account_id}/branding-images/light This lists the light theme banding images of the subtenant account.
list GET: /v3/accounts
me GET: /v3/accounts/me This is provided by the SDK to avoid listing to retrieve the user's own Account.
read GET: /v3/accounts/{account_id}
trusted_certificates GET: /v3/accounts/{account_id}/trusted-certificates This lists the trusted certificates of the subtenant account.
update PUT: /v3/accounts/{account_id}
user_invitations GET: /v3/accounts/{account_id}/user-invitations This lists the user invitations of the subtenant account.
users GET: /v3/accounts/{account_id}/users This lists the users of the subtenant account.

Accounts: API Key

Entity Method REST API Mapping Notes
create POST: /v3/api-keys
delete DELETE: /v3/api-keys/{apikey_id}
list GET: /v3/api-keys
me GET: /v3/api-keys/me This is provided by the SDK to avoid listing to retrieve the user's own API Key.
read GET: /v3/api-keys/{apikey_id}
update PUT: /v3/api-keys/{apikey_id}

Accounts: Subtenant API Key

Entity Method REST API Mapping
create POST: /v3/accounts/{account_id}/api-keys
delete DELETE: /v3/accounts/{account_id}/api-keys/{apikey_id}
read GET: /v3/accounts/{account_id}/api-keys/{apikey_id}
update PUT: /v3/accounts/{account_id}/api-keys/{apikey_id}

Accounts: Subtenant User

Entity Method REST API Mapping Notes
create POST: /v3/accounts/{account_id}/users
delete DELETE: /v3/accounts/{account_id}/users/{user_id}
read GET: /v3/accounts/{account_id}/users/{user_id}
update PUT: /v3/accounts/{account_id}/users/{user_id} The API field 'email' is not used by the SDK.
The API field 'status' is not used by the SDK.
The API field 'two_factor_auth_enabled' is not used by the SDK.
validate_email POST: /v3/accounts/{account_id}/users/{user_id}/validate-email

Accounts: Subtenant User Invitation

Entity Method REST API Mapping
create POST: /v3/accounts/{account_id}/user-invitations
delete DELETE: /v3/accounts/{account_id}/user-invitations/{invitation_id}
read GET: /v3/accounts/{account_id}/user-invitations/{invitation_id}

Accounts: User

Entity Method REST API Mapping Notes
create POST: /v3/users
delete DELETE: /v3/users/{user_id}
list GET: /v3/users
read GET: /v3/users/{user_id}
update PUT: /v3/users/{user_id} The API field 'email' is not used by the SDK.
The API field 'status' is not used by the SDK.
The API field 'two_factor_auth_enabled' is not used by the SDK.

Accounts: User Invitation

Entity Method REST API Mapping
create POST: /v3/user-invitations
delete DELETE: /v3/user-invitations/{invitation_id}
list GET: /v3/user-invitations
read GET: /v3/user-invitations/{invitation_id}

Branding: Dark Theme Color

Entity Method REST API Mapping
delete DELETE: /v3/branding-colors/dark/{reference}
list GET: /v3/branding-colors/dark
read GET: /v3/branding-colors/dark/{reference}
update PUT: /v3/branding-colors/dark/{reference}

Branding: Dark Theme Image

Entity Method REST API Mapping
delete POST: /v3/branding-images/dark/{reference}/clear
list GET: /v3/branding-images/dark
read GET: /v3/branding-images/dark/{reference}
update POST: /v3/branding-images/dark/{reference}/upload-multipart

Branding: Light Theme Color

Entity Method REST API Mapping
delete DELETE: /v3/branding-colors/light/{reference}
list GET: /v3/branding-colors/light
read GET: /v3/branding-colors/light/{reference}
update PUT: /v3/branding-colors/light/{reference}

Branding: Light Theme Image

Entity Method REST API Mapping
delete POST: /v3/branding-images/light/{reference}/clear
list GET: /v3/branding-images/light
read GET: /v3/branding-images/light/{reference}
update POST: /v3/branding-images/light/{reference}/upload-multipart

Branding: Subtenant Dark Theme Color

Entity Method REST API Mapping
delete DELETE: /v3/accounts/{account_id}/branding-colors/dark/{reference}
read GET: /v3/accounts/{account_id}/branding-colors/dark/{reference}
update PUT: /v3/accounts/{account_id}/branding-colors/dark/{reference}

Branding: Subtenant Dark Theme Image

Entity Method REST API Mapping
delete POST: /v3/accounts/{account_id}/branding-images/dark/{reference}/clear
read GET: /v3/accounts/{account_id}/branding-images/dark/{reference}
update POST: /v3/accounts/{account_id}/branding-images/dark/{reference}/upload-multipart

Branding: Subtenant Light Theme Color

Entity Method REST API Mapping
delete DELETE: /v3/accounts/{account_id}/branding-colors/light/{reference}
read GET: /v3/accounts/{account_id}/branding-colors/light/{reference}
update PUT: /v3/accounts/{account_id}/branding-colors/light/{reference}

Branding: Subtenant Light Theme Image

Entity Method REST API Mapping
delete POST: /v3/accounts/{account_id}/branding-images/light/{reference}/clear
read GET: /v3/accounts/{account_id}/branding-images/light/{reference}
update POST: /v3/accounts/{account_id}/branding-images/light/{reference}/upload-multipart

Device Update: Campaign Device Metadata

The following fields are renamed between the REST API and SDK:

Entity Method REST API Mapping
read GET: /v3/update-campaigns/{campaign_id}/campaign-device-metadata/{campaign_device_metadata_id}/

Device Update: Campaign Statistics

Entity Method REST API Mapping
events GET: /v3/update-campaigns/{campaign_id}/statistics/{summary_status_id}/event_types/
list GET: /v3/update-campaigns/{campaign_id}/statistics/
read GET: /v3/update-campaigns/{campaign_id}/statistics/{summary_status_id}

Device Update: Campaign Statistics Events

Entity Method REST API Mapping
read GET: /v3/update-campaigns/{campaign_id}/statistics/{summary_status_id}/event_types/{event_type_id}

Device Update: Firmware Image

The following fields are renamed between the REST API and SDK:

Entity Method REST API Mapping Notes
create POST: /v3/firmware-images/ This is not a standard create method as it uploads a file which creates an entity which contains URIs to the uploaded file.
delete DELETE: /v3/firmware-images/{image_id}/
list GET: /v3/firmware-images/
read GET: /v3/firmware-images/{image_id}/

Device Update: Firmware Manifest

The following fields are renamed between the REST API and SDK:

Entity Method REST API Mapping Notes
create POST: /v3/firmware-manifests/ This is not a standard create method as it uploads a file (or files) which creates an entity which contains URIs to the uploaded file(s).
delete DELETE: /v3/firmware-manifests/{manifest_id}/
list GET: /v3/firmware-manifests/
read GET: /v3/firmware-manifests/{manifest_id}/

Device Update: Update Campaign

The following REST API fields are not used by the SDK:

The following properties are added by the SDK:

Entity Method REST API Mapping
archive POST: /v3/update-campaigns/{campaign_id}/archive
create POST: /v3/update-campaigns/
delete DELETE: /v3/update-campaigns/{campaign_id}/
device_metadata GET: /v3/update-campaigns/{campaign_id}/campaign-device-metadata/
list GET: /v3/update-campaigns/
read GET: /v3/update-campaigns/{campaign_id}/
start POST: /v3/update-campaigns/{campaign_id}/start
stop POST: /v3/update-campaigns/{campaign_id}/stop
update PUT: /v3/update-campaigns/{campaign_id}/

Devices: Device

Entity Method REST API Mapping
add_to_group POST: /v3/device-groups/{device-group-id}/devices/add/
create POST: /v3/devices/
delete DELETE: /v3/devices/{id}/
list GET: /v3/devices/
read GET: /v3/devices/{id}/
remove_from_group POST: /v3/device-groups/{device-group-id}/devices/remove/
renew_certificate POST: /v3/devices/{device-id}/certificates/{certificate-name}/renew
update PUT: /v3/devices/{id}/

Devices: Device Enrollment

Entity Method REST API Mapping
create POST: /v3/device-enrollments
delete DELETE: /v3/device-enrollments/{id}
list GET: /v3/device-enrollments
read GET: /v3/device-enrollments/{id}

Devices: Device Enrollment Bulk Create

Entity Method REST API Mapping
create POST: /v3/device-enrollments-bulk-uploads
download_errors_report_file N/A
download_full_report_file N/A
read GET: /v3/device-enrollments-bulk-uploads/{id}

Devices: Device Enrollment Bulk Delete

Entity Method REST API Mapping
delete POST: /v3/device-enrollments-bulk-deletes
download_errors_report_file N/A
download_full_report_file N/A
read GET: /v3/device-enrollments-bulk-deletes/{id}

Devices: Device Enrollment Denial

Entity Method REST API Mapping
list GET: /v3/device-enrollment-denials
read GET: /v3/device-enrollment-denials/{device_enrollment_denial_id}

Devices: Device Events

Entity Method REST API Mapping
list GET: /v3/device-events/
read GET: /v3/device-events/{device_event_id}/

Devices: Device Group

Entity Method REST API Mapping
add_device POST: /v3/device-groups/{device-group-id}/devices/add/
create POST: /v3/device-groups/
delete DELETE: /v3/device-groups/{device-group-id}/
devices GET: /v3/device-groups/{device-group-id}/devices/
list GET: /v3/device-groups/
read GET: /v3/device-groups/{device-group-id}/
remove_device POST: /v3/device-groups/{device-group-id}/devices/remove/
update PUT: /v3/device-groups/{device-group-id}/

Security: Certificate Enrollment

Entity Method REST API Mapping
list GET: /v3/certificate-enrollments
read GET: /v3/certificate-enrollments/{certificate-enrollment-id}

Security: Certificate Issuer

Entity Method REST API Mapping
create POST: /v3/certificate-issuers
delete DELETE: /v3/certificate-issuers/{certificate-issuer-id}
list GET: /v3/certificate-issuers
read GET: /v3/certificate-issuers/{certificate-issuer-id}
update PUT: /v3/certificate-issuers/{certificate-issuer-id}
verify POST: /v3/certificate-issuers/{certificate-issuer-id}/verify

Security: Certificate Issuer Config

The following REST API fields are not used by the SDK:

Entity Method REST API Mapping
create POST: /v3/certificate-issuer-configurations
delete DELETE: /v3/certificate-issuer-configurations/{certificate-issuer-configuration-id}
get_default GET: /v3/certificate-issuer-configurations/lwm2m
list GET: /v3/certificate-issuer-configurations
read GET: /v3/certificate-issuer-configurations/{certificate-issuer-configuration-id}
update PUT: /v3/certificate-issuer-configurations/{certificate-issuer-configuration-id}

Security: Developer Certificate

The following fields are renamed between the REST API and SDK:

Entity Method REST API Mapping
create POST: /v3/developer-certificates
delete DELETE: /v3/trusted-certificates/{cert_id}
get_trusted_certificate_info GET: /v3/trusted-certificates/{cert_id}
read GET: /v3/developer-certificates/{developerCertificateId}

Security: Pre Shared Key

The following properties are added by the SDK:

Entity Method REST API Mapping
create POST: /v2/device-shared-keys
delete DELETE: /v2/device-shared-keys/{endpoint_name}
list GET: /v2/device-shared-keys
read GET: /v2/device-shared-keys/{endpoint_name}

Security: Server Credentials

Entity Method REST API Mapping
get_bootstrap GET: /v3/server-credentials/bootstrap
get_lwm2m GET: /v3/server-credentials/lwm2m

Security: Subtenant Trusted Certificate

The following REST API fields are not used by the SDK:

The following properties are added by the SDK:

Entity Method REST API Mapping Notes
create POST: /v3/accounts/{account_id}/trusted-certificates Signature is not used by the SDK as it is a deprecated field.
delete DELETE: /v3/accounts/{account_id}/trusted-certificates/{cert_id}
get_developer_certificate_info GET: /v3/developer-certificates/{developerCertificateId}
read GET: /v3/accounts/{account_id}/trusted-certificates/{cert_id}
update PUT: /v3/accounts/{account_id}/trusted-certificates/{cert_id} Signature is not used by the SDK as it is a deprecated field.

Security: Trusted Certificate

The following REST API fields are not used by the SDK:

The following properties are added by the SDK:

Entity Method REST API Mapping Notes
create POST: /v3/trusted-certificates Signature is not used by the SDK as it is a deprecated field.
delete DELETE: /v3/trusted-certificates/{cert_id}
get_developer_certificate_info GET: /v3/developer-certificates/{developerCertificateId}
list GET: /v3/trusted-certificates
read GET: /v3/trusted-certificates/{cert_id}
update PUT: /v3/trusted-certificates/{cert_id} Signature is not used by the SDK as it is a deprecated field.

Appendix: API to SDK Reference

This lists the API endpoints and where they are supported in the SDK.

Account Management API

REST API Endpoint HTTP Method SDK Interface SDK Entity/Module SDK Method Notes
/v3/accounts GET Foundation
Account
list

POST Foundation
Account
create

/v3/accounts/me GET Foundation
Account
me
This is provided by the SDK to avoid listing to retrieve the user's own Account.
PUT Foundation
Account
update
After retrieving the resource using the `me` method, it can modified using using this SDK method.
/v3/accounts/{account_id} GET Foundation
Account
read

PUT Foundation
Account
update

/v3/accounts/{account_id}/api-keys GET Foundation
Account
api_keys
This lists the api keys of the subtenant account.
POST Foundation
Subtenant API Key
create

/v3/accounts/{account_id}/api-keys/{apikey_id} GET Foundation
Subtenant API Key
read

PUT Foundation
Subtenant API Key
update

DELETE Foundation
Subtenant API Key
delete

/v3/accounts/{account_id}/branding-colors/dark GET Foundation
Account
dark_theme_branding_colors
This lists the dark theme banding colors of the subtenant account.
PUT Foundation
Subtenant Dark Theme Color
update
Bulk operation is not appriate for SDK's entity model, this functionality is covered by the update method.
/v3/accounts/{account_id}/branding-colors/dark/{reference} GET Foundation
Subtenant Dark Theme Color
read

PUT Foundation
Subtenant Dark Theme Color
update

DELETE Foundation
Subtenant Dark Theme Color
delete

/v3/accounts/{account_id}/branding-colors/light GET Foundation
Account
light_theme_branding_colors
This lists the light theme banding colors of the subtenant account.
PUT Foundation
Subtenant Light Theme Color
update
Bulk operation is not appriate for SDK's entity model, this functionality is covered by the update method.
/v3/accounts/{account_id}/branding-colors/light/{reference} GET Foundation
Subtenant Light Theme Color
read

PUT Foundation
Subtenant Light Theme Color
update

DELETE Foundation
Subtenant Light Theme Color
delete

/v3/accounts/{account_id}/branding-images/dark GET Foundation
Account
dark_theme_branding_images
This lists the dark theme banding images of the subtenant account.
/v3/accounts/{account_id}/branding-images/dark/{reference} GET Foundation
Subtenant Dark Theme Image
read

/v3/accounts/{account_id}/branding-images/dark/{reference}/clear POST Foundation
Subtenant Dark Theme Image
delete

/v3/accounts/{account_id}/branding-images/dark/{reference}/upload POST Foundation
Subtenant Dark Theme Image
update
The multipart endpoint is used by the SDKs as it offers the same functionality as the standard upload endpoint.
/v3/accounts/{account_id}/branding-images/dark/{reference}/upload-multipart POST Foundation
Subtenant Dark Theme Image
update

/v3/accounts/{account_id}/branding-images/light GET Foundation
Account
light_theme_branding_images
This lists the light theme banding images of the subtenant account.
/v3/accounts/{account_id}/branding-images/light/{reference} GET Foundation
Subtenant Light Theme Image
read

/v3/accounts/{account_id}/branding-images/light/{reference}/clear POST Foundation
Subtenant Light Theme Image
delete

/v3/accounts/{account_id}/branding-images/light/{reference}/upload POST Foundation
Subtenant Light Theme Image
update
The multipart request is more generic and better supported by SDKs.
/v3/accounts/{account_id}/branding-images/light/{reference}/upload-multipart POST Foundation
Subtenant Light Theme Image
update

/v3/accounts/{account_id}/trusted-certificates GET Foundation
Account
trusted_certificates
This lists the trusted certificates of the subtenant account.
POST Foundation
Subtenant Trusted Certificate
create
Signature is not used by the SDK as it is a deprecated field.
/v3/accounts/{account_id}/trusted-certificates/{cert_id} GET Foundation
Subtenant Trusted Certificate
read

PUT Foundation
Subtenant Trusted Certificate
update
Signature is not used by the SDK as it is a deprecated field.
DELETE Foundation
Subtenant Trusted Certificate
delete

/v3/accounts/{account_id}/user-invitations GET Foundation
Account
user_invitations
This lists the user invitations of the subtenant account.
POST Foundation
Subtenant User Invitation
create

/v3/accounts/{account_id}/user-invitations/{invitation_id} GET Foundation
Subtenant User Invitation
read

DELETE Foundation
Subtenant User Invitation
delete

/v3/accounts/{account_id}/users GET Foundation
Account
users
This lists the users of the subtenant account.
POST Foundation
Subtenant User
create

/v3/accounts/{account_id}/users/{user_id} GET Foundation
Subtenant User
read

PUT Foundation
Subtenant User
update

DELETE Foundation
Subtenant User
delete

/v3/accounts/{account_id}/users/{user_id}/validate-email POST Foundation
Subtenant User
validate_email

/v3/api-keys GET Foundation
API Key
list

POST Foundation
API Key
create

/v3/api-keys/me GET Foundation
API Key
me
This is provided by the SDK to avoid listing to retrieve the user's own API Key.
PUT Foundation
API Key
update
After retrieving the resource using the `me` method, it can modified using using this SDK method.
/v3/api-keys/{apikey_id} GET Foundation
API Key
read

PUT Foundation
API Key
update

DELETE Foundation
API Key
delete

/v3/branding-colors/dark GET Foundation
Dark Theme Color
list

PUT Foundation
Dark Theme Color
update
Bulk operation is not appriate for SDK's entity model, this functionality is covered by the update method.
/v3/branding-colors/dark/{reference} GET Foundation
Dark Theme Color
read

PUT Foundation
Dark Theme Color
update

DELETE Foundation
Dark Theme Color
delete

/v3/branding-colors/light GET Foundation
Light Theme Color
list

PUT Foundation
Light Theme Color
update
Bulk operation is not appriate for SDK's entity model, this functionality is covered by the update method.
/v3/branding-colors/light/{reference} GET Foundation
Light Theme Color
read

PUT Foundation
Light Theme Color
update

DELETE Foundation
Light Theme Color
delete

/v3/branding-images/dark GET Foundation
Dark Theme Image
list

/v3/branding-images/dark/{reference} GET Foundation
Dark Theme Image
read

/v3/branding-images/dark/{reference}/clear POST Foundation
Dark Theme Image
delete

/v3/branding-images/dark/{reference}/upload POST Foundation
Dark Theme Image
update
The multipart endpoint is used by the SDKs as it offers the same functionality as the standard upload endpoint.
/v3/branding-images/dark/{reference}/upload-multipart POST Foundation
Dark Theme Image
update

/v3/branding-images/light GET Foundation
Light Theme Image
list

/v3/branding-images/light/{reference} GET Foundation
Light Theme Image
read

/v3/branding-images/light/{reference}/clear POST Foundation
Light Theme Image
delete

/v3/branding-images/light/{reference}/upload POST Foundation
Light Theme Image
update
The multipart request is more generic and better supported by SDKs.
/v3/branding-images/light/{reference}/upload-multipart POST Foundation
Light Theme Image
update

/v3/developer-certificates POST Foundation
Developer Certificate
create

/v3/developer-certificates/{developerCertificateId} GET Foundation
Foundation
Foundation
Developer Certificate
Subtenant Trusted Certificate
Trusted Certificate
read
get_developer_certificate_info
get_developer_certificate_info



/v3/server-credentials GET Foundation
Foundation
Server Credentials
Server Credentials
get_bootstrap
get_lwm2m
The information returned by this endpoint can be obtained by calling `get_bootstrap`.
The information returned by this endpoint can be obtained by calling `get_lwm2m`.
/v3/server-credentials/bootstrap GET Foundation
Server Credentials
get_bootstrap

/v3/server-credentials/lwm2m GET Foundation
Server Credentials
get_lwm2m

/v3/trusted-certificates GET Foundation
Trusted Certificate
list

POST Foundation
Trusted Certificate
create
Signature is not used by the SDK as it is a deprecated field.
/v3/trusted-certificates/{cert_id} GET Foundation
Foundation
Developer Certificate
Trusted Certificate
get_trusted_certificate_info
read


PUT Foundation
Trusted Certificate
update
Signature is not used by the SDK as it is a deprecated field.
DELETE Foundation
Foundation
Developer Certificate
Trusted Certificate
delete
delete


/v3/user-invitations GET Foundation
User Invitation
list

POST Foundation
User Invitation
create

/v3/user-invitations/{invitation_id} GET Foundation
User Invitation
read

DELETE Foundation
User Invitation
delete

/v3/users GET Foundation
User
list

POST Foundation
User
create

/v3/users/{user_id} GET Foundation
User
read

PUT Foundation
User
update

DELETE Foundation
User
delete

Billing API

REST API Endpoint HTTP Method SDK Interface SDK Entity/Module SDK Method
/v3/billing-report GET Legacy
Billing API
get_report_overview
/v3/billing-report-active-devices GET Legacy
Billing API
get_report_active_devices
/v3/billing-report-firmware-updates GET Legacy
Billing API
get_report_firmware_updates
/v3/service-packages GET Legacy
Billing API
get_service_packages
/v3/service-packages-quota GET Legacy
Billing API
get_quota_remaining
/v3/service-packages-quota-history GET Legacy
Billing API
get_quota_history

Bootstrap API

REST API Endpoint HTTP Method SDK Interface SDK Entity/Module SDK Method
/v2/device-shared-keys GET Foundation
Pre Shared Key
list
POST Foundation
Pre Shared Key
create
/v2/device-shared-keys/{endpoint_name} GET Foundation
Pre Shared Key
read
DELETE Foundation
Pre Shared Key
delete

Certificate Enrollment API

REST API Endpoint HTTP Method SDK Interface SDK Entity/Module SDK Method
/v3/certificate-enrollments GET Foundation
Certificate Enrollment
list
/v3/certificate-enrollments/{certificate-enrollment-id} GET Foundation
Certificate Enrollment
read
/v3/devices/{device-id}/certificates/{certificate-name}/renew POST Foundation
Device
renew_certificate

Connect API

REST API Endpoint HTTP Method SDK Interface SDK Entity/Module SDK Method Notes
/v2/device-requests/{device-id} POST Legacy
Legacy
Legacy
Connect API
Connect API
Connect API
get_resource_value
set_resource_value
execute_resource



/v2/endpoints/{device-id} GET Legacy
Connect API
list_resources

/v2/endpoints/{device-id}/{resourcePath} GET Legacy
Connect API
get_resource_value
This functionality is available from the stated method but this endpoint is not used by the SDK.
PUT Legacy
Connect API
set_resource_value
This functionality is available from the stated method but this endpoint is not used by the SDK.
POST Legacy
Connect API
execute_resource
This functionality is available from the stated method but this endpoint is not used by the SDK.
/v2/notification/callback PUT Legacy
Connect API
update_webhook

GET Legacy
Connect API
get_webhook

DELETE Legacy
Connect API
delete_webhook

/v2/notification/pull GET Legacy
Connect API
start_notifications
This endpoint is called indirectly to receive asynchronous subscription and resource value data.
DELETE Legacy
Connect API
stop_notifications

/v2/subscriptions DELETE Legacy
Connect API
delete_presubscriptions
This functionality is available from the stated method but this endpoint is not used by the SDK.
PUT Legacy
Legacy
Connect API
Connect API
update_presubscriptions
delete_presubscriptions


GET Legacy
Connect API
list_presubscriptions

/v2/subscriptions/{device-id} GET Legacy
Connect API
list_device_subscriptions

DELETE Legacy
Connect API
delete_device_subscriptions

/v2/subscriptions/{device-id}/{resourcePath} PUT Legacy
Connect API
add_resource_subscription

DELETE Legacy
Connect API
delete_resource_subscription

GET Legacy
Connect API
get_resource_subscription

Connect Statistics API

REST API Endpoint HTTP Method SDK Interface SDK Entity/Module SDK Method
/v3/metrics GET Legacy
Connect API
list_metrics

Customer's Third Party CA API

REST API Endpoint HTTP Method SDK Interface SDK Entity/Module SDK Method Notes
/v3/certificate-issuer-configurations POST Foundation
Certificate Issuer Config
create

GET Foundation
Certificate Issuer Config
list

/v3/certificate-issuer-configurations/lwm2m GET Foundation
Certificate Issuer Config
get_default

PUT Foundation
Certificate Issuer Config
update
After retrieving the resource using the `lwm2m` method, it can modified using using this SDK method.
/v3/certificate-issuer-configurations/{certificate-issuer-configuration-id} GET Foundation
Certificate Issuer Config
read

PUT Foundation
Certificate Issuer Config
update

DELETE Foundation
Certificate Issuer Config
delete

/v3/certificate-issuers GET Foundation
Certificate Issuer
list

POST Foundation
Certificate Issuer
create

/v3/certificate-issuers/{certificate-issuer-id} GET Foundation
Certificate Issuer
read

PUT Foundation
Certificate Issuer
update

DELETE Foundation
Certificate Issuer
delete

/v3/certificate-issuers/{certificate-issuer-id}/verify POST Foundation
Certificate Issuer
verify

Device Directory API

REST API Endpoint HTTP Method SDK Interface SDK Entity/Module SDK Method Notes
/v3/device-events/ GET Foundation
Device Events
list

/v3/device-events/{device_event_id}/ GET Foundation
Device Events
read

/v3/device-groups/ GET Foundation
Device Group
list

POST Foundation
Device Group
create

/v3/device-groups/{device-group-id}/ DELETE Foundation
Device Group
delete

GET Foundation
Device Group
read

PUT Foundation
Device Group
update

/v3/device-groups/{device-group-id}/devices/ GET Foundation
Device Group
devices

/v3/device-groups/{device-group-id}/devices/add/ POST Foundation
Foundation
Device
Device Group
add_to_group
add_device


/v3/device-groups/{device-group-id}/devices/remove/ POST Foundation
Foundation
Device
Device Group
remove_from_group
remove_device


/v3/device-queries/ GET Legacy
Device Directory API
list_queries

POST Legacy
Device Directory API
add_query

/v3/device-queries/{query_id}/ DELETE Legacy
Device Directory API
delete_query

GET Legacy
Device Directory API
get_query

PUT Legacy
Device Directory API
update_query

/v3/devicelog/ GET N/A
N/A
N/A
Endpoint is deprecated and is not supported by the SDKs
/v3/devicelog/{device_event_id}/ GET N/A
N/A
N/A
Endpoint is deprecated and is not supported by the SDKs
/v3/devices/ GET Foundation
Device
list

POST Foundation
Device
create

/v3/devices/{id}/ DELETE Foundation
Device
delete

GET Foundation
Device
read

PUT Foundation
Device
update

Device Enrollment Denial API

REST API Endpoint HTTP Method SDK Interface SDK Entity/Module SDK Method
/v3/device-enrollment-denials GET Foundation
Device Enrollment Denial
list
/v3/device-enrollment-denials/{device_enrollment_denial_id} GET Foundation
Device Enrollment Denial
read

Enrollment API

REST API Endpoint HTTP Method SDK Interface SDK Entity/Module SDK Method
/v3/device-enrollments POST Foundation
Device Enrollment
create
GET Foundation
Device Enrollment
list
/v3/device-enrollments-bulk-deletes POST Foundation
Device Enrollment Bulk Delete
delete
/v3/device-enrollments-bulk-deletes/{id} GET Foundation
Device Enrollment Bulk Delete
read
/v3/device-enrollments-bulk-uploads POST Foundation
Device Enrollment Bulk Create
create
/v3/device-enrollments-bulk-uploads/{id} GET Foundation
Device Enrollment Bulk Create
read
/v3/device-enrollments/{id} GET Foundation
Device Enrollment
read
DELETE Foundation
Device Enrollment
delete

Update Service API

REST API Endpoint HTTP Method SDK Interface SDK Entity/Module SDK Method Notes
/v3/firmware-images/ GET Foundation
Firmware Image
list

POST Foundation
Firmware Image
create
This is not a standard create method as it uploads a file which creates an entity which contains URIs to the uploaded file.
/v3/firmware-images/{image_id}/ DELETE Foundation
Firmware Image
delete

GET Foundation
Firmware Image
read

/v3/firmware-manifests/ GET Foundation
Firmware Manifest
list

POST Foundation
Firmware Manifest
create
This is not a standard create method as it uploads a file (or files) which creates an entity which contains URIs to the uploaded file(s).
/v3/firmware-manifests/{manifest_id}/ DELETE Foundation
Firmware Manifest
delete

GET Foundation
Firmware Manifest
read

/v3/update-campaigns/ GET Foundation
Update Campaign
list

POST Foundation
Update Campaign
create

/v3/update-campaigns/{campaign_id}/ DELETE Foundation
Update Campaign
delete

GET Foundation
Update Campaign
read

PUT Foundation
Update Campaign
update

/v3/update-campaigns/{campaign_id}/archive POST Foundation
Update Campaign
archive

/v3/update-campaigns/{campaign_id}/campaign-device-metadata/ GET Foundation
Update Campaign
device_metadata

/v3/update-campaigns/{campaign_id}/campaign-device-metadata/{campaign_device_metadata_id}/ GET Foundation
Campaign Device Metadata
read

/v3/update-campaigns/{campaign_id}/metrics GET N/A
N/A
N/A
Endpoint is deprecated: Use the statistics endpoint instead.
/v3/update-campaigns/{campaign_id}/start POST Foundation
Update Campaign
start

/v3/update-campaigns/{campaign_id}/statistics/ GET Foundation
Campaign Statistics
list

/v3/update-campaigns/{campaign_id}/statistics/{summary_status_id} GET Foundation
Campaign Statistics
read

/v3/update-campaigns/{campaign_id}/statistics/{summary_status_id}/event_types/ GET Foundation
Campaign Statistics
events

/v3/update-campaigns/{campaign_id}/statistics/{summary_status_id}/event_types/{event_type_id} GET Foundation
Campaign Statistics Events
read

/v3/update-campaigns/{campaign_id}/stop POST Foundation
Update Campaign
stop