Getting started with the Azure IoT Central Rest API

Azure IoT Central is a SaaS platform for IoT projects.

If you are looking for a way to manage and monitor your IoT devices outside the Azure Portal or are not able to build your own IoT platform, IoT Central is the place to be. And you can extend this portal with custom Azure resources using the export functionality.

All you need is to have browser access to Azure IoT Central. You can even run it for free for seven days to test it out. Also, the first two devices registered are free too.

Once you have worked with Azure IoT central, you have mastered it using the portal. If you want to scale up eg. the number of devices or users, automation of your tasks becomes necessary.

For this, Azure IoT Central offers a Rest API.

Let’s check this API out.

The API is quite extensive and devices in Operation groups:

There are groups for eg. handling device templatesand groups for handling devices.

For example, the API for getting the latest telemetry of a device looks like this:

GET https://{subdomain}.{centralDnsSuffixInPath}/api/preview/devices/{device_id}/components/{component_name}/telemetry/{telemetry_name}

For this particular call, you have to fill in these values:

If everything is configured well, this call will return the latest values of a certain telemetry part:

Still, if you call it this way, nothing returns. You will get a message that access is denied!

This is because there is just one thing missing if you want to make a call like this: authorization. You need access right to the Rest API call.

Note: This blog shows you how to communicate using the API tokens. According to this it should be possible to connect with Azure Active Directory user account bearer tokens. This is out of scope for this blog. A hint is given here.

Access is managed by IoT Central using the Administration portal:

There, you can add one or more API tokens.

There are three different kinds of tokens, depending on the roles:

  • Administrator: manage and control every part of the application, including billing
  • Builder: can manage every part of the app, but can’t make changes on the Administration or Continuous Data Export tabs
  • Operator: can monitor device health and status. They aren’t allowed to make changes to device templates or to administer the application. Operators can add and delete devices, manage device sets, and run analytics and jobs.

Note: This means some API calls are not allowed for certain roles.

We need to generate an API key that represents one of these roles.

For example, we generate a key for the builder role. Just give it a name:

Once generated, we receive the key once and only once:

Keep in mind, the key is only applicable for 365 days. So you have to renew it within a year!

Making a call

With this API key, we can now make a call.

As an example, I wrote this piece of C# code to make the actual call:

public async static void GetIoTCentralLatestTelemetryValue()
{
    Console.WriteLine("Read current telemetry value...");

    string restUriGet = "https://store-manager-15368.azureiotcentral.com/api/preview/devices/storemon-sim-001/telemetry/humid";

    var apiKey = "SharedAccessSignature sr=364....."; // taken from the dialog

    using var client = new HttpClient();
    client.DefaultRequestHeaders.Add("Authorization", apiKey);

    var res = await client.GetAsync(restUriGet);

    var jsonString = await res.Content.ReadAsStringAsync();

    Console.WriteLine($"Sent {res.StatusCode} {jsonString}");
}

Note: just put in the API key you got from the IoT Central Portal. Do not change it.

Once this code executed, a JSON value is returned:

So, this is all you need to start automating Azure IoT Central.

Creating a device template

A more elaborate action is adding a device template:

public async static void CreateTemplate()
{
    string restUri = "https://store-manager-15368.azureiotcentral.com/api/preview/deviceTemplates/store_monitoring_device";

    using var client = new HttpClient();
    client.DefaultRequestHeaders.Add("Authorization", apiKey);

    var json = File.ReadAllText("template.txt");

    var content = new StringContent(json, Encoding.UTF8, "application/json");

    var res = client.PutAsync(restUri, content).Result;

    var jsonString = await res.Content.ReadAsStringAsync();

    Console.WriteLine($"Template create: {res.StatusCode} {jsonString}");
}

Where the template could like like:

{
    "@id": "dtmi:contoso:store_monitor;1",
    "types": [
      "ModelDefinition",
      "DeviceModel"
    ],
    "displayName": "Store monitoring device",
    "capabilityModel": {
      "@id": "dtmi:contoso:store_monitor_dcm;1",
      "@type": "CapabilityModel",
      "displayName": "Environment Sensor Capability Model",
      "contents": [
        {
          "@type": [
            "Telemetry"
          ],
          "description": "Current temperature on the device",
          "displayName": "Temperature",
          "name": "temp",
          "schema": "double"
        },
        {
          "@type": [
            "Telemetry"
          ],
          "description": "Current humidity on the device",
          "displayName": "Humidity",
          "name": "humid",
          "schema": "double"
        },
        {
          "@type": [
            "Property"
          ],
          "description": "The brightness level for the light on the device. Can be specified as 1 (high), 2 (medium), 3 (low)",
          "displayName": "Brightness Level",
          "name": "brightness",
          "writable": true,
          "schema": "long"
        },
        {
          "@type": [
            "Command"
          ],
          "description": "This command reboots the device after delay seconds.",
          "displayName": "Reboot device",
          "name": "reboot",
          "request": {
            "@type": [
              "SchemaField"
            ],
            "displayName": "Seconds delay before reboot",
            "name": "delay",
            "schema": "long"
          }
        }
      ]
    },
    "solutionModel": {
      "@type": [
        "SolutionModel"
      ],
      "@id": "dtmi:contoso:store_monitor_sm;1",
      "cloudProperties": [
        {
          "@type": "CloudProperty",
          "displayName": "Store Name",
          "name": "storename",
          "schema": "string",
          "valueDetail": {
            "@type": "StringValueDetail"
          }
        }
      ],
      "initialValues": [],
      "overrides": []
    },
    "@context": [
      "dtmi:iotcentral:context;2",
      "dtmi:dtdl:context;2"
    ]
}

So we are also capable of posting (or using PUT) to add something to the IoT Central Portal.

Adding a simulated device

Finally, I demonstrate how to add a device:

public async static void CreateDevice()
{
    string restUri = "https://store-manager-15368.azureiotcentral.com/api/preview/devices/storemon-sim-001";

    using var client = new HttpClient();
    client.DefaultRequestHeaders.Add("Authorization", apiKey);

    dynamic deviceRegistration = new
    {
        instanceOf = "store_monitoring_device",
        simulated = true,
        displayName = "Simulated store monitoring device - 001",
        approved = true
    };

    var json = JsonConvert.SerializeObject(deviceRegistration);

    var content = new StringContent(json, Encoding.UTF8, "application/json");

    var res = client.PutAsync(restUri, content).Result;

    var jsonString = await res.Content.ReadAsStringAsync();

    Console.WriteLine($"Template create: {res.StatusCode} {jsonString}");
}

Again, this is accepted by the API.

A device is generated in IoT Central:

Custom roles

IoT Central allows you to create custom roles:

These roles can have their own specific API keys:

Conclusion

You have now seen how to access the API using Rest calls written in C#.

If you are interested in getting started with the Rest API, please take a moment to learn and practice using this MS Learn module. You do not even have to show an Azure subscription!

It takes just less than an hour to master that API. You will also learn eg. how to generate Azue IoT Centrla portals using the CLI.