Developer Guide


The message broker supports the use of the MQTT protocol to publish and subscribe and the HTTPS protocol to publish. Both protocols are supported through IP version 4 and IP version 6. The message broker also supports MQTT over the WebSocket protocol.


MQTT is a widely adopted lightweight messaging protocol designed for constrained devices. For more information, go to MQTT. Although the AWS IoT message broker implementation is based on MQTT version 3.1.1, it deviates from the specification as follows:

  • In AWS IoT, subscribing to a topic with Quality of Service (QoS) 0 means a message will be delivered zero or more times. A message may be delivered more than once. Messages delivered more than once may be sent with a different packet ID. In these cases, the DUP flag is not set.

  • AWS IoT does not support publishing and subscribing with QoS 2. The AWS IoT message broker does not send a PUBACK or SUBACK when QoS 2 is requested.

  • The QoS levels for publishing and subscribing to a topic have no relation to each other. One client can subscribe to a topic using QoS1 while another client can publish to the same topic using QoS0.

  • When responding to a connection request, the message broker sends a CONNACK message. This message contains a flag to indicate if the connection is resuming a previous session. The value of this flag may be incorrect when two MQTT clients connect with the same client ID simultaneously.

  • When a client subscribes to a topic, there may be a delay between the time the message broker sends a SUBACK and the time the client starts receiving new matching messages.

  • The MQTT specification provides a provision for the publisher to request that the broker retain the last message sent to a topic and send it to all future topic subscribers. AWS IoT does not support retained messages. If a request is made to retain messages, the connection is disconnected.

  • The message broker uses the client ID to identify each client. The client ID is passed in from the client to the message broker as part of the MQTT payload. Two clients with the same client ID are not allowed to be connected concurrently to the message broker. When a client connects to the message broker using a client ID that another client is using, a CONNACK message will be sent to both clients and the currently connected client will be disconnected.

  • The message broker does not support persistent sessions (clean session set to 0). All sessions are assumed to be clean sessions and messages are not stored across sessions. If an MQTT client sends a message with the clean session attribute set to false, the client will be disconnected.

  • On rare occasions, the message broker may resend the same logical publish message with a different packet ID.

  • The message broker does not guarantee the order in which messages and ACK are received.


The message broker supports clients connecting with the HTTP protocol using a REST API. Clients can publish by sending a POST message to <AWS IoT Endpoint>/topics/<url_encoded_topic_name>?qos=1".

MQTT Over the WebSocket Protocol

AWS IoT supports MQTT over the WebSocket protocol to enable browser-based and remote applications to send and receive data from AWS IoT-connected devices using AWS credentials. AWS credentials are specified using AWS signature version 4. For more information, see AWS Signature Version 4. WebSocket support is available on port tcp:443, which allows messages to pass through most firewalls and web proxies.

A WebSocket connection is initiated on a client by sending an HTTP GET request. The URL you use is of the following form:


Specifies the WebSocket protocol.


Your AWS account-specific AWS IoT endpoint. You can use the AWS IoT CLI describe-endpoint command to find this endpoint.


The AWS region of your AWS account.


Specifies you will be sending MQTT messages over the WebSocket protocol.

When the server responds, the client sends an upgrade request to indicate to the server it will communicate using the WebSocket protocol. After the server acknowledges the upgrade request, all communication is performed using the WebSocket protocol. The WebSocket implementation you use acts as a transport protocol. The data you send over the WebSocket protocol are MQTT messages.

Using the WebSocket Protocol in a Web Application

The WebSocket implementation provided by most web browsers does not allow the modification of HTTP headers, so you must add the signature version 4 information to the query string. For more information, see Adding Signing Information to the Query String.

The following JavaScript defines some utility functions used in generating a signature version 4 request.

   * utilities to do sigv4
   * @class SigV4Utils
  function SigV4Utils(){}

  SigV4Utils.sign = function(key, msg){
    var hash = CryptoJS.HmacSHA256(msg, key);
    return hash.toString(CryptoJS.enc.Hex);

  SigV4Utils.sha256 = function(msg) {
    var hash = CryptoJS.SHA256(msg);
    return hash.toString(CryptoJS.enc.Hex);

  SigV4Utils.getSignatureKey = function(key, dateStamp, regionName, serviceName) {
    var kDate = CryptoJS.HmacSHA256(dateStamp, 'AWS4' + key);
    var kRegion = CryptoJS.HmacSHA256(regionName, kDate);
    var kService = CryptoJS.HmacSHA256(serviceName, kRegion);
    var kSigning = CryptoJS.HmacSHA256('aws4_request', kService);
    return kSigning;

To create a Signature Version 4 request

  1. Create a canonical request for Signature Version 4.

    The following JavaScript code creates a canonical request:

    var time = moment.utc();
    var dateStamp = time.format('YYYYMMDD');
    var amzdate = dateStamp + 'T' + time.format('HHmmss') + 'Z';
    var service = 'iotdevicegateway';
    var region = this.options.regionName;
    var secretKey = this.options.secretKey;
    var accessKey = this.options.accessKey;
    var algorithm = 'AWS4-HMAC-SHA256';
    var method = 'GET';
    var canonicalUri = '/mqtt';
    var host = this.options.endpoint;
    var credentialScope = dateStamp + '/' + region + '/' + service + '/' + 'aws4_request';
    var canonicalQuerystring = 'X-Amz-Algorithm=AWS4-HMAC-SHA256';
    canonicalQuerystring += '&X-Amz-Credential=' + encodeURIComponent(accessKey + '/' + credentialScope);
    canonicalQuerystring += '&X-Amz-Date=' + amzdate;
    canonicalQuerystring += '&X-Amz-SignedHeaders=host';
    var canonicalHeaders = 'host:' + host + '\n';
    var payloadHash = SigV4Utils.sha256('');
    var canonicalRequest = method + '\n' + canonicalUri + '\n' + canonicalQuerystring + '\n' + canonicalHeaders + '\nhost\n' + payloadHash;
        console.log('canonicalRequest ' + canonicalRequest);
  2. Create a string to sign, generate a signing key, and sign the string.

    Take the canonical URL you created in the previous step and assemble it into a string to sign. You do this by creating a string composed of the hashing algorithm, the date, the credential scope, and the SHA of the canonical request. Next, generate the signing key and sign the string, as shown in the following JavaScript code.

        var stringToSign = algorithm + '\n' +  amzdate + '\n' +  credentialScope + '\n' +  SigV4Utils.sha256(canonicalRequest);
        var signingKey = SigV4Utils.getSignatureKey(secretKey, dateStamp, region, service);
        var signature = SigV4Utils.sign(signingKey, stringToSign);
  3. Add the signing information to the request.

    The following JavaScript code shows how to add the signing information to the query string.

        canonicalQuerystring += '&X-Amz-Signature=' + signature;
        var requestUrl = 'wss://' + host + canonicalUri + '?' + canonicalQuerystring;
  4. If you have session credentials (from an STS server, AssumeRole, or Amazon Cognito), append the session token to the end of the URL string after signing:

    requestUrl += "&X-Amz-Security-Token=" + encodeURIComponent(sessionToken);
  5. Open the WebSocket.

    The following JavaScript code shows how to create a Paho MQTT client and call CONNECT to AWS IoT. The endpoint argument is your AWS account-specific endpoint. The clientId is a text identifier that is unique among all clients simultaneously connected in your AWS account.

    var client = new Paho.MQTT.Client(requestUrl, clientId);
    var connectOptions = {
        onSuccess: function(){
            // connect succeeded
        useSSL: true,
        timeout: 3,
        mqttVersion: 4,
        onFailure: function() {
            // connect failed

Using the WebSocket Protocol in a Mobile Application

We recommend using one of the AWS IoT Device SDKs to connect your device to AWS IoT when making a WebSocket connection. The following AWS IoT Device SDKs support WebSocket-based MQTT-connections to AWS IoT:

You can find a reference implementation for connecting a web application to AWS IoT using MQTT over the WebSocket protocol here: AWS Labs WebSocket sample.

If you are using a programming or scripting language that is not currently supported, any existing WebSocket library can be used as long as the initial WebSocket upgrade request (HTTP POST) is signed using AWS Signature Version 4. Some MQTT clients, such as Eclipse Paho for JavaScript, support the WebSocket protocol natively.