How to send events to IotHub REST endpoint?

It is not a common scenario, but there are obviously cases when telemetry events have to be sent to IoTHub by using of HTTP/REST.

You might have a very simple device, which cannot implement MQTT or AMQP. If device can provide HTTP/S communication it will be able to send telemetry events to IoTHub. It is important to know, that that IotHub does not allow you to send events by using HTTP. In this case you MUST use HTTP/S.This is a common rule for all Azure services.

More general information about REST services supported by IotHub can be found here. More information related to telemetry endpoint can be found here.

Sometimes, there are applications, which implement dedicated connectors to IotHub. Such applications usually provide Web-Hook to integrate with external systems. For example a Web-Hook might be invoked every time, when telemetry event is observed by application. In this case you can configure IotHub to be invoked by application's Web-Hook.

By using of Web-Hooks you will probably have issue to generate required authorization header. IotHub use connection string to generate SAS tokens, but connection string itself cannot be used in authorization header.

To work around this, you can create SAS token with very long expiration time and set it as authorization header in the configuration of Web-Hook.

This is the POST request which has to be sent to IotHub:

https://IOTHUBNAME.azure-devices.net/devices/DEVICENAME/messages/events?api-version=2018-06-30

Authorization: SharedAccessSignature sr=IOTHUBNAME.azure-devices.net%2Fdevices%2FDEVICENAME&sig=c******=iothubowner

To create a token you can use following code:


public void CreateSasTokenTest()
{
    TestHelpers.CreateToken("IOTHUBNAME.azure-devices.net/devices/DEVICENAME",
    "iothubowner", "Bn4/TLarGFu0T***uMBdCYb0QhU=");
}
        
public static string CreateToken(string resourceUri, string policyName, string key, int expiryInSeconds = 36000)
{
    TimeSpan fromEpochStart = DateTime.UtcNow - new DateTime(1970, 1, 1);
    string expiry = Convert.ToString((int)fromEpochStart.TotalSeconds +
    expiryInSeconds);

    string stringToSign = WebUtility.UrlEncode(resourceUri) + "\n" + expiry;

    HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(key));
    string signature = Convert.ToBase64String(hmac.ComputeHas
    (Encoding.UTF8.GetBytes(stringToSign)));

    string token = String.Format(CultureInfo.InvariantCulture,
    "SharedAccessSignature sr={0}&sig={1}&se={2}", WebUtility.UrlEncod
    (resourceUri), WebUtility.UrlEncode(signature), expiry);

    if (!String.IsNullOrEmpty(policyName))
    {
        token += "&skn=" + policyName;
    }

    return token;
}

You can create .NET console application, paste this code and run by invoking of CreateSasTokenTest().