NAV Navbar
Raw Shell JavaScript Node.js C++
  • Introduction
  • Environments
  • Basic concepts
  • Authentication
  • Client libraries
  • API methods
  • Notifications
  • Errors
  • Introduction

    The Catenis Enterprise API is organized around REST. The API has predictable, resource-oriented URLs, and uses HTTP response status codes to indicate the outcome of an API method request.

    It uses built-in HTTP features, like HTTP verbs and headers, which are understood by off-the-shelf HTTP clients. It supports cross-origin resource sharing, allowing you to securely interact with the Catenis Enterprise API from a client-side web application — though you should never expose your API access secret in any public website's client-side code.

    A JSON is returned in response to any API method request, even when an error takes place.

    Environments

    Beta

    The Catenis Enterprise API is currently only available in beta, which connects with the testnet Bitcoin network.

    Version

    The beta environment is currently at version 0.5 of the Catenis Enterprise API, which is the latest available version.

    Base API URL

    https://beta.catenis.io/api/0.5/

    Basic concepts

    Catenis entities

    Virtual device

    The virtual device — or some times simply referred to as device — is the fundamental entity that is used to interact with the Catenis Enterprise system.

    Each virtual device has a unique device ID, which is assigned by the system when a new virtual device is created.

    Optionally, a virtual device can also be identified by an end user provided product unique ID.

    Each virtual device also has a system assigned API access secret, which is used for authenticating the virtual device when making an API request.

    An optional name can also be assigned to a virtual device. That name, however, only serves as a label and cannot be used to select or otherwise reference a specific virtual device.

    Client

    The client is the entity that maps to an end user. A client can have one or more virtual devices.

    Like virtual devices, each client has a unique client ID, which is assigned by the system when a new client is created.

    Each client is associated with a system provided user account. The client user account is used by the end user to access the system and do administrative tasks, like creating new virtual devices, and adding service credits.

    Catenis node

    The Catenis node is the entity used to aggregate the Catenis Enterprise services for a specific region or user premises.

    Catenis nodes are identified by their index. Currently, only one public, central Catenis node — referred to as the Catenis Hub node — is available. The Catenis Hub node has index 0.

    Clients are defined within a given Catenis node. So, a Catenis node will typically have one or more clients.

    Permission rights

    Catenis Enterprise provides a permission mechanism where a virtual device — the controlling device — can allow or deny other virtual devices — the controlled devices — to interact with it in a given predefined way. Such predefined controlled interactions are referred to as permission events.

    Permission events

    The following permission events are currently defined:

    Event name Description
    receive-notify-new-msg Receive notification of new message from a device
    receive-notify-msg-read Receive notification of message read by a device
    send-read-msg-confirm Send read message confirmation to a device
    receive-msg Receive message from a device
    disclose-main-props Disclose device's main properties (name, product unique ID) to a device
    disclose-identity-info Disclose device's basic identification information to a device

    A permission event is described as an action where the controlling device is the subject and the controlled device is the object of such action.

    Thus, taking the receive-msg permission event as an example, if a device is given allow right in regards to that permission event, it means that the controlling device will be able to receive messages sent from that device. Otherwise — if a device is given deny right instead —, the controlling device shall not receive any messages sent from that device.

    Permission levels

    For a given pair of permission event and controlling device, the permission rights can be set at four different levels:

    Permission right evaluation

    For a given pair of permission event and controlling device, the effective permission right for a given (controlled) device is evaluated according to the following procedure:

    1. Starting at the device level, we check if the permission right for that (controlled) device is set. If so, that is the permission right that is in effect.

    2. Otherwise, we go to the level above, and check if the permission right for the client to which the (controlled) device belongs is set. If so, that is the permission right that is in effect.

    3. Otherwise, we go to the level above, and check if the permission right for the Catenis node where the client to which the (controlled) device belongs is defined is set. If so, that is permission right that is in effect.

    4. Otherwise, whatever permission right that is set at the system level is what is in effect.

    Authentication

    General

    The Catenis Enterprise API methods require authentication on each request. The authentication mechanism used is a SHA-256 Keyed-Hash Message Authentication Code (HMAC-SHA256). It is based on the AWS Signature version 4 authentication scheme, although it is not the same, and thus libraries that implement the AWS authentication scheme cannot be used with the Catenis Enterprise API.

    With HMAC-SHA256, the server and the client share a secret signing key. The signing key lives in the respective client application and is never transmitted across the line. Instead, the key is used to generate a hash for signing the message contents.

    To authenticate and use the services provided by the Catenis Enterprise API methods, one must have an active client account, and use one of their virtual devices to actually consume the service. The virtual device's device ID and API access secret are then used to generate the authentication token that needs to be sent with every request.

    Usage

    To properly call a Catenis Enterprise API method, the client application must authenticate the request before sending it, for which the following general steps must be taken:

    1. Constructs an HTTP request for the API method that needs to be called;
    2. Signs the request using the virtual device's API access secret;
    3. Adds an Authorization header containing, amongst other things, the virtual device's device ID and the calculated signature.

    Alternatively, one of the supplied Catenis API client libraries can be used, which makes issuing and authenticating Catenis Enterprise API requests much simpler.

    Detailed specification

    This section describes how to issue and authenticate an HTTP request that conforms with the Catenis HMAC-SHA256 authentication scheme used by the Catenis Enterprise API.

    HTTP headers

    Not yet authenticated request (used in following examples):

    POST /api/0.5/messages/log HTTP/1.1
    Host: beta.catenis.io
    User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
    X-BCoT-Timestamp: 20180127T121358Z
    Content-Type: application/json; charset=utf-8
    Connection: close
    Content-Length: 95
    
    {"message":"This is only a test","options":{"encoding":"utf8","encrypt":true,"storage":"auto"}}
    

    The HTTP request that needs to be authenticated must include at least the following HTTP headers, known as the essential headers:

    Header Contents
    Host The host name. Example: beta.catenis.io
    X-BCoT-Timestamp The current UTC time in ISO 8601 format. Example: 20170125T000000Z

    Aside from the essential headers, after the request is authenticated, it will include an HTTP Authorization header, since the authentication itself consists of adding that header to the request.

    The following sections describe the elements that are needed for composing the contents of the Authorization header.

    Conformed request

    String literal:

      "POST\n/api/0.5/message/send\nhost:api.catenis.com\nx-bcot-timestamp:20180127T121358Z\n\n792cdbeef04dc33e8ebb4974070ec5a75bd1e3a6c5ef49b1c3ec1b87152694c6\n"
    

    Printed text:

      POST
      api/0.5/message/send
      host:api.catenis.com
      x-bcot-timestamp:20180127T121358Z
    
      792cdbeef04dc33e8ebb4974070ec5a75bd1e3a6c5ef49b1c3ec1b87152694c6
    
    

    The conformed request is defined as:

    <http_verb> + "\n" + <api_endpoint_path> + "\n" + <essential_headers> + "\n" + <payload_hash> + "\n"

    Where:

    Term Description
    <http_verb> The HTTP method of the request. One of: GET, POST, PUT, HEAD, or DELETE.
    <api_endpoint_path> The complete path of the URL of the API method endpoint. Example: /api/0.5/message/send
    <essential_headers> A list showing the essential headers with their respective contents. Each item is defined as: <header_name> + ":" + <header_contents> + "\n"; where <header_name> is the lowercase name of the header, and <header_contents> is the contents of the header. Example: host:beta.catenis.io\nx-bcot-timestamp:20170125T103246Z\n
    <payload_hash> Defined as: HEX(SHA256(<payload>)); where <payload> is the payload (or body) of the HTTP request. If the request has no payload, an empty string should be used in its place.

    String to sign

    String literal:

      "CTN1-HMAC-SHA256\n20180127T121358Z\n20180127/ctn1_request\n6c5a53a5aed35fe4dc27146c7d01d548cd810b644b0dcada1d1416fe82cad6f0\n"
    

    Printed text:

      CTN1-HMAC-SHA256
      20180127T121358Z
      20180127/ctn1_request
      6c5a53a5aed35fe4dc27146c7d01d548cd810b644b0dcada1d1416fe82cad6f0
    
    

    The string to sign is defined as:

    "CTN1-HMAC-SHA256" + "\n" + <timestamp> + "\n" + <scope> + "\n" + <conformed_request_hash> + "\n"

    Where:

    Term Description
    <timestamp> Current UTC time in ISO 8601 format. Example: 20180127T121358Z
    <scope> Defined as: <date> + “/ctn1_request”; where <date> is a date formatted as YYYYMMDD. Example: 20180127/ctn1_request
    <conformed_request_hash> Defined as: HEX(SHA256(<conformed_request>)); where <conformed_request> is the conformed request element as defined in the Conformed request section above.

    Signing key

    String literal:

      "\xe9\x94\x04\xc8\xbb\xc2\x5d\x02\x56\xff\xa5\x8f\x6e\x72\x17\x9d\xe5\xdc\x7f\x67\xf9\xe5\x8f\x84\x32\xaf\x76\x18\xbb\xb7\x99\xe5"
    

    The signing key is defined as:

    HMAC-SHA256(<date_key>, “ctn1_request”)

    Term Description
    <date_key> Defined as: HMAC-SHA256(“CTN1" + <api_access_secret>, <scope_date>); where <api_access_secret> is the virtual device's API access secret, and <scope_date> is the <date> component of the <scope> element as defined in String to sign section above.

    Signature

    String literal:

      "70db4ecb53a69dfdc8dcef5934a4d12df93c14f3178fe7797261c4f66144a44b"
    

    Printed text:

      70db4ecb53a69dfdc8dcef5934a4d12df93c14f3178fe7797261c4f66144a44b
    

    The signature is defined as:

    HEX(HMAC-SHA256(<signing_key>, <string_to_sign>))

    Term Description
    <signing_key> The signing key element as defined in the Signing key section above
    <string_to_sign> The string to sign element as defined in the String to sign section above

    Authorization header

    Authenticated request:

    POST /api/0.5/messages/log HTTP/1.1
    Host: beta.catenis.io
    User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
    X-BCoT-Timestamp: 20180127T121358Z
    Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180127/ctn1_request,Signature=70db4ecb53a69dfdc8dcef5934a4d12df93c14f3178fe7797261c4f66144a44b
    Content-Type: application/json; charset=utf-8
    Connection: close
    Content-Length: 95
    
    {"message":"This is only a test","options":{"encoding":"utf8","encrypt":true,"storage":"auto"}}
    

    The contents of the Authorization header is defined as:

    "CTN1-HMAC-SHA256" + <space> + "Credential=" + <device_id> + "/" + <scope> + "," + "Signature=" + <signature>

    Where:

    Term Description
    <space> A sequence of one or more whitespace characters.
    <device_id> The virtual device's device ID. Example: dnN3Ea43bhMTHtTvpytS
    <scope> The <scope> element as defined in the String to sign section above. Example: 20180127/ctn1_request
    <signature> The signature element as defined in the Signature section above.
    Status code Error message
    401 Authorization failed; authorization value not well formed
    Authorization failed; invalid device or signature
    Authorization failed; missing required HTTP headers
    Authorization failed; signature date not well formed
    Authorization failed; signature date out of bounds
    Authorization failed; timestamp not well formed
    Authorization failed; timestamp not within acceptable time variation

    Client libraries

    To make it easier for developers to interact with the Catenis Enterprise API and overcome the hurdles of authenticating each request, Blockchain of Things provide open-source client libraries for different programming languages and environments.

    The following libraries are currently available:

    Paw extensions

    Aside from the Catenis API client libraries listed above, Blockchain of Things have also made available a set of customized Paw extensions that can be used to facilitate the creation and use of Catenis API requests from within Paw on a Mac, allowing for easy prototyping and testing of the Catenis Enterprise API methods.

    API methods

    The following is a comprehensive list of the methods available in version 0.5 of the Catenis Enterprise API.

    Log Message

    Records a message on the blockchain.

    Sample request:

    POST /api/0.5/messages/log HTTP/1.1
    X-BCoT-Timestamp: 20180127T173944Z
    Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180127/ctn1_request, Signature=35e284726b17533d087f75ebea2bda5792011e503c391132d4e14fdb67fdaf30
    Content-Type: application/json; charset=utf-8
    Host: beta.catenis.io
    Connection: close
    User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
    Content-Length: 95
    
    {"message":"This is only a test","options":{"encoding":"utf8","encrypt":true,"storage":"auto"}}
    
    curl -X "POST" "https://beta.catenis.io/api/0.5/messages/log" \
         -H 'X-BCoT-Timestamp: 20180127T174023Z' \
         -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180127/ctn1_request, Signature=72d51cd708e5a81ee1a50b33c72f98c906084b183a60904cd0ce3f4119659581' \
         -H 'Content-Type: application/json; charset=utf-8' \
         -d $'{
      "message": "This is only a test",
      "options": {
        "encoding": "utf8",
        "encrypt": true,
        "storage": "auto"
      }
    }'
    
    <script src="CatenisAPIClientJS.min.js"></script>
    
    <script language="JavaScript">
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    ctnApiClient.logMessage('This is only a test', {
            encoding: 'utf8',
            encrypt: true,
            storage: 'auto'
        },
        function (err, data) {
            if (err) {
                // Process error
            }
            else {
                // Process returned data
                console.log('ID of logged message:', data.messageId);
            }
    });
    </script>
    
    var CtnApiClient = require('catenis-api-client');
    
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    ctnApiClient.logMessage('This is only a test', {
            encoding: 'utf8',
            encrypt: true,
            storage: 'auto'
        },
        function (err, data) {
            if (err) {
                // Process error
            }
            else {
                // Process returned data
                console.log('ID of logged message:', data.messageId);
            }
    });
    
    #include "CatenisApiClient.h"
    #include <string>
    
    std::string device_id("dnN3Ea43bhMTHtTvpytS");
    
    ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "beta");
    
    std::string response_data;
    ctn::MethodOption options("utf8", true, "auto");
    
    if (ctnApiClient.logMessage("My message", response_data, options)) {
      cout << "ID of logged message: " << response_data << endl;
    }
    

    Request

    POST /messages/log

    Parameters

    A JSON containing the following properties:

    Property Type Description
    message String The message to record.
    options Object
      encoding String (optional, default: utf8) Value identifying the encoding of the message. Valid options: utf8, base64, hex.
      encrypt Boolean (optional, default: true) Indicates whether message should be encrypted before storing it.
      storage String (optional, default: auto) Value identifying where the message should be stored. Valid options: auto, embedded, external. The value embedded specifies that the message should be stored on the blockchain transaction itself; the value external specifies that the message should be stored in an external repository; and the value auto is used to specify that the message be embedded whenever possible otherwise it should be stored in the external storage.

    Sample response:

    {
      "status": "success",
      "data": {
        "messageId": "muczbRbcgo3F8XoC6ejE"
      }
    }
    

    Success response

    A JSON containing the following properties:

    Property Type Description
    status String The value success, indicating that the request was successful.
    data Object The actual data returned in response to the API request.
      messageId String ID of the logged message.

    Possible errors

    Status code Error message
    400 Device is deleted
    Device is not active
    Invalid parameters
    Message too long to be embedded
    No credit to log message
    500 Internal server error
    503 System currently not available; please try again at a later time

    Send Message

    Records a message on the blockchain directing it to another virtual device.

    The virtual device that sends the message is referred to as the origin device, and the virtual device to which the message is sent is referred to as the target device.

    Sample request:

    POST /api/0.5/messages/send HTTP/1.1
    X-BCoT-Timestamp: 20180207T201833Z
    Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180207/ctn1_request, Signature=fc1c92fbdb248e2d0aa363babd2d4b32342e29a93a2782fb76bd4e3a45ce3488
    Content-Type: application/json; charset=utf-8
    Host: beta.catenis.io
    Connection: close
    User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
    Content-Length: 187
    
    {"targetDevice":{"id":"dv3htgvK7hjnKx3617Re","isProdUniqueId":false},"message":"This is only a test","options":{"readConfirmation":true,"encoding":"utf8","encrypt":true,"storage":"auto"}}
    
    curl -X "POST" "https://beta.catenis.io/api/0.5/messages/send" \
         -H 'X-BCoT-Timestamp: 20180207T201727Z' \
         -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180207/ctn1_request, Signature=3a8a28c50ce40cac7586df4231a7bee4ad6d08de3b289f96984c4458bf86c370' \
         -H 'Content-Type: application/json; charset=utf-8' \
         -d $'{
      "message": "This is only a test",
      "options": {
        "storage": "auto",
        "encoding": "utf8",
        "readConfirmation": true,
        "encrypt": true
      },
      "targetDevice": {
        "id": "dv3htgvK7hjnKx3617Re",
        "isProdUniqueId": false
      }
    }'
    
    <script src="CatenisAPIClientJS.min.js"></script>
    
    <script language="JavaScript">
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    ctnApiClient.sendMessage('This is only a test', 'dv3htgvK7hjnKx3617Re', {
            readConfirmation: true,
            encoding: 'utf8',
            encrypt: true,
            storage: 'auto'
        },
        function (err, data) {
            if (err) {
                // Process error
            }
            else {
                // Process returned data
                console.log('ID of sent message:', data.messageId);
            }
    });
    </script>
    
    var CtnApiClient = require('catenis-api-client');
    
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    ctnApiClient.sendMessage('This is only a test', 'dv3htgvK7hjnKx3617Re', {
            readConfirmation: true,
            encoding: 'utf8',
            encrypt: true,
            storage: 'auto'
        },
        function (err, data) {
            if (err) {
                // Process error
            }
            else {
                // Process returned data
                console.log('ID of sent message:', data.messageId);
            }
    });
    
    #include "CatenisApiClient.h"
    #include <string>
    
    std::string device_id("dnN3Ea43bhMTHtTvpytS");
    
    ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "beta");
    
    std::string response_data;
    ctn::MethodOption options("utf8", true, "auto");
    
    if (ctnApiClient.sendMessage("This is only a test", response_data, options)) {
        cout << "ID of sent message: " << response_data << endl;
    }
    

    Request

    POST /messages/send

    Parameters

    A JSON containing the following properties:

    Property Type Description
    targetDevice Object
      id String The ID of the virtual device to which the message is directed. Should be a device ID unless isProdUniqueId is set.
      isProdUniqueId Boolean (optional, default: false) Indicates whether the supplied ID is a product unique ID.
    message String The message to send.
    options Object
      readConfirmation Boolean (optional, default: false) Indicates whether message should be sent with read confirmation enabled. This should be used when the origin device intends to be notified when the target device first reads the message.
      encoding String (optional, default: utf8) Value identifying the encoding of the message. Valid options: utf8, base64, hex.
      encrypt Boolean (optional, default: true) Indicates whether message should be encrypted before storing it.
      storage String (optional, default: auto) Value identifying where the message should be stored. Valid options: auto, embedded, external. The value embedded specifies that the message should be stored on the blockchain transaction itself; the value external specifies that the message should be stored in an external repository; and the value auto is used to specify that the message be embedded whenever possible otherwise it should be stored in the external storage.

    Sample respose:

    {
      "status": "success",
      "data": {
        "messageId": "muczbRbcgo3F8XoC6ejE"
      }
    }
    

    Success response

    A JSON containing the following properties:

    Property Type Description
    status String The value success, indicating that the request was successful.
    data Object The actual data returned in response to the API request.
      messageId String ID of the sent message.

    Possible errors

    Status code Error message
    400 Device is deleted
    Device is not active
    Invalid parameters
    Invalid target device
    Message too long to be embedded
    No credit to send message
    500 Internal server error
    503 System currently not available; please try again at a later time

    Read Message

    Retrieves the contents of a message that had been previously recorded on the blockchain.

    Sample request:

    GET /api/0.5/messages/mDWPuD5kjCsEiNEEWwrW?encoding=utf8 HTTP/1.1
    X-BCoT-Timestamp: 20180215T112048Z
    Authorization: CTN1-HMAC-SHA256 Credential=dmM2Dz32agLSGsSuoxsR/20180215/ctn1_request, Signature=10b1299fdf935544b44e3e1e8de7d3f3df03df9ddc35db0127d5ab0cafa36cbb
    Host: beta.catenis.io
    Connection: close
    User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
    
    curl "https://beta.catenis.io/api/0.5/messages/mDWPuD5kjCsEiNEEWwrW?encoding=utf8" \
         -H 'X-BCoT-Timestamp: 20180215T112120Z' \
         -H 'Authorization: CTN1-HMAC-SHA256 Credential=dmM2Dz32agLSGsSuoxsR/20180215/ctn1_request, Signature=84ddc0f0e3a3cadab6011b18962912bdf62bfcd2234e0984513a1856fd88c1c1'
    
    <script src="CatenisAPIClientJS.min.js"></script>
    
    <script language="JavaScript">
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    var messageId = 'mDWPuD5kjCsEiNEEWwrW';
    
    ctnApiClient.readMessage(messageId, 'utf8', function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            console.log('Message read:', data.message);
    
            if (data.action === 'send') {
                console.log('Message originally sent from:', data.from);
            }
        }
    });
    </script>
    
    var CtnApiClient = require('catenis-api-client');
    
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    var messageId = 'mDWPuD5kjCsEiNEEWwrW';
    
    ctnApiClient.readMessage(messageId, 'utf8', function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            console.log('Message read:', data.message);
    
            if (data.action === 'send') {
                console.log('Message originally sent from:', data.from);
            }
        }
    });
    
    #include "CatenisApiClient.h"
    #include <string>
    
    std::string device_id("dnN3Ea43bhMTHtTvpytS");
    
    ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "beta");
    
    std::string response_data;
    std::string message_id("mDWPuD5kjCsEiNEEWwrW");
    
    if (ctnApiClient.readMessage(message_id, response_data, "utf8")) {
      cout << "Message read: " << response_data << endl;
    }
    

    Request

    GET /messages/:messageId

    Parameters

    Sample response:

    {
      "status": "success",
      "data": {
        "action": "send",
        "from": {
          "deviceId": "dv3htgvK7hjnKx3617Re",
          "name": "Catenis device #1"
        },
        "message": "This is only a test"
      }
    }
    

    Success response

    A JSON containing the following properties:

    Property Type Description
    status String The value success, indicating that the request was successful.
    data Object The actual data returned in response to the API request.
      action String Action originally performed on the message. Possible values: log, send. The value log indicates that this is a logged message, and the value send indicates that this is a sent message.
      from Object (only returned for sent messages) Identifies the virtual device that sent the message — the origin device.
        deviceId String The device ID of the origin device.
        name String (only returned if origin device has this data, and the virtual device issuing the request has the necessary permission right) The name of the origin device.
        prodUniqueId String (only returned if origin device has this data, and the virtual device issuing the request has the necessary permission right) The product unique ID of the origin device.
      message String The contents of the message formatted using the specified encoding.

    Possible errors

    Status code Error message
    400 Device is deleted
    Device is not active
    Invalid message ID
    Invalid parameters
    403 No permission to read message
    500 Internal server error
    503 System currently not available; please try again at a later time

    Retrieve Message Container

    Gets information about the place where a previously recorded message — either logged or sent — is actually stored.

    Sample request:

    GET /api/0.5/messages/mDWPuD5kjCsEiNEEWwrW/container HTTP/1.1
    X-BCoT-Timestamp: 20180215T200325Z
    Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180215/ctn1_request, Signature=f06dc359270c2a3a91326ef2e7fd5506fd75dc9740b2609ed796ce01b3f92afb
    Host: beta.catenis.io
    Connection: close
    User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
    
    curl "https://beta.catenis.io/api/0.5/messages/mDWPuD5kjCsEiNEEWwrW/container" \
         -H 'X-BCoT-Timestamp: 20180215T200350Z' \
         -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180215/ctn1_request, Signature=7e50993e18975294f7f22aae7ee7ef4e4d68425502e38961c40743b1f72194eb'
    
    <script src="CatenisAPIClientJS.min.js"></script>
    
    <script language="JavaScript">
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    var messageId = 'mDWPuD5kjCsEiNEEWwrW';
    
    ctnApiClient.retrieveMessageContainer(messageId, function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            if (data.blockchain) {
                console.log('ID of blockchain transaction containing the message:', data.blockchain.txid);
            }
            else if (data.externalStorage.ipfs) {
                console.log('IPFS reference to message:', data.externalStorage.ipfs);
            }
        }
    });
    </script>
    
    var CtnApiClient = require('catenis-api-client');
    
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    var messageId = 'mDWPuD5kjCsEiNEEWwrW';
    
    ctnApiClient.retrieveMessageContainer(messageId, function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            if (data.blockchain) {
                console.log('ID of blockchain transaction containing the message:', data.blockchain.txid);
            }
            else if (data.externalStorage.ipfs) {
                console.log('IPFS reference to message:', data.externalStorage.ipfs);
            }
        }
    });
    
    #include "CatenisApiClient.h"
    #include <string>
    
    std::string device_id("dnN3Ea43bhMTHtTvpytS");
    
    ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "beta");
    
    std::string response_data;
    std::string message_id("mDWPuD5kjCsEiNEEWwrW");
    
    if (ctnApiClient.retrieveMessageContainer(message_id, response_data)) {
      cout << "Message container: " << response_data << endl;
    }
    

    Request

    GET /messages/:messageId/container

    Parameters

    Sample response:

    {
      "status": "success",
      "data": {
        "blockchain": {
          "txid": "f624e66c5fc424fbde00b5c134fa0f4fe45ed2f7d0e4540cb0b302815f2ea7f8",
          "isConfirmed": false
        },
        "externalStorage": {
          "ipfs": "QmfWZ7GCNouMNHjkz9BBJazCsfvR5hY9j62HVh5K6uzrwd"
        }
      }
    }
    

    Success response

    A JSON containing the following properties:

    Property Type Description
    status String The value success, indicating that the request was successful.
    data Object The actual data returned in response to the API request.
      blockchain Object
        txid String The ID of the blockchain transaction where the message was recorded.
        confirmed Boolean Indicates whether the blockchain transaction has already been confirmed.
      externalStorage String (only returned if message is stored on an external storage rather than on the blockchain transaction itself)
        ipfs String The hash used to reference the message on IPFS.

    Possible errors

    Status code Error message
    400 Device is deleted
    Device is not active
    Invalid message ID
    Invalid parameters
    403 No permission to retrieve message container
    500 Internal server error
    503 System currently not available; please try again at a later time

    List Messages

    Retrieves a list of message entries that satisfy a given search criteria.

    A virtual device can use it to identify newly received messages, for instance.

    Sample request:

    GET /api/0.5/messages?action=send&direction=inbound&fromDeviceIds=dv3htgvK7hjnKx3617Re&readState=unread&startDate=2018-01-01T00:00:00Z&endDate=2018-02-28T23:59:59Z HTTP/1.1
    X-BCoT-Timestamp: 20180216T135036Z
    Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180216/ctn1_request, Signature=bb8a7853798df41e6f9af1a900da4c3cecc161265ec85649f8b883678e8993ed
    Host: beta.catenis.io
    Connection: close
    User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
    
    curl "https://beta.catenis.io/api/0.5/messages?action=send&direction=inbound&fromDeviceIds=dv3htgvK7hjnKx3617Re&readState=unread&startDate=2018-01-01T00:00:00Z&endDate=2018-02-28T23:59:59Z" \
         -H 'X-BCoT-Timestamp: 20180216T135101Z' \
         -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180216/ctn1_request, Signature=c0bb81382db103e30859056646bfa17759e9e8f73778abc0245fdbdb54be4656'
    
    <script src="CatenisAPIClientJS.min.js"></script>
    
    <script language="JavaScript">
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    ctnApiClient.listMessages({
            action: 'send',
            direction: 'inbound',
            fromDeviceIds: 'dv3htgvK7hjnKx3617Re',
            readState: 'unread',
            startDate: '20180101T000000Z',
            endDate: '20180228T235959Z'
        },
        function (err, data) {
            if (err) {
                // Process error
            }
            else {
                // Process returned data
                if (data.msgCount > 0) {
                    console.log('Returned messages:', data.messages);
    
                    if (data.countExceeded) {
                        console.log('Warning: not all messages fulfilling search criteria have been returned!';
                    }
                }
            }
    });
    </script>
    
    var CtnApiClient = require('catenis-api-client');
    
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    ctnApiClient.listMessages({
            action: 'send',
            direction: 'inbound',
            fromDeviceIds: 'dv3htgvK7hjnKx3617Re',
            readState: 'unread',
            startDate: '20180101T000000Z',
            endDate: '20180228T235959Z'
        },
        function (err, data) {
            if (err) {
                // Process error
            }
            else {
                // Process returned data
                if (data.msgCount > 0) {
                    console.log('Returned messages:', data.messages);
    
                    if (data.countExceeded) {
                        console.log('Warning: not all messages fulfilling search criteria have been returned!';
                    }
                }
            }
    });
    
    #include "CatenisApiClient.h"
    #include <string>
    
    std::string device_id("dnN3Ea43bhMTHtTvpytS");
    
    ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "beta");
    
    std::string response_data;
    
    if (ctnApiClient.listMessages(response_data, "send", "inbound", "dv3htgvK7hjnKx3617Re", null, null, null, "unread", "20180101T000000Z", "20180228T235959Z")) {
      cout << "Returned messages: " << response_data << endl;
    }
    

    Request

    GET /messages

    Parameters

    Sample response:

    {
      "status": "success",
      "data": {
        "messages": [
          {
            "messageId": "mospScAtxyX8ytD9Cq58",
            "action": "log",
            "read": false,
            "date": "2018-01-29T23:25:47.865Z"
          },
          {
            "messageId": "mNEWqgSMAeDAmBAkBDWr",
            "action": "send",
            "direction": "outbound",
            "to": {
              "deviceId": "dv3htgvK7hjnKx3617Re",
              "name": "deviceB",
              "prodUniqueId": "XYZABC001"
            },
            "readConfirmationEnabled": true,
            "read": true,
            "date": "2018-01-29T23:27:39.331Z"
          }
        ],
        "msgCount": 2,
        "countExceeded": false
      }
    }
    

    Success response

    A JSON containing the following properties:

    Property Type Description
    status String The value success, indicating that the request was successful.
    data Object The actual data returned in response to the API request.
      messages Array(Object) The returned list of message information entries including the messages that satisfies the search criteria. The list is sorted in ascending order in regard to the returned date field.
        messageId String The ID of the message.
        action String Action originally performed on the message. Possible values: log, send. The value log indicates that this is a logged message, and the value send indicates that this is a sent message.
        direction String (only returned for sent messages) The direction of the sent message. Possible values: inbound, outbound. The value inbound indicates that this is a message received by the virtual device issuing the request, and the value outbound indicates that this is a message sent by the device issuing the request.
        from Object (only returned for sent messages) Identifies the virtual device that sent the message — the origin device.
          deviceId String The device ID of the origin device.
          name String (only returned if origin device has this data, and the device issuing the request has the necessary permission right) The name of the origin device.
          prodUniqueId String (only returned if origin device has this data, and the device issuing the request has the necessary permission right) The product unique ID of the origin device.
        to Object (only returned for sent messages) Identifies the device to which the message had been sent — the target device.
          deviceId String The device ID of the target device.
          name String (only returned if target device has this data, and the device issuing the request has the necessary permission right) The name of the target device.
          prodUniqueId String (only returned if target device has this data, and the device issuing the request has the necessary permission right) The product unique ID of the target device.
        readConfirmationEnabled Boolean (only returned for outbound sent messages) Indicates whether message had been sent with read confirmation enabled.
        read Boolean (not returned for outbound sent messages sent with read confirmation not enabled) Indicates whether the message had already been read.
        date String ISO 8601 formatted date and time when the message had been: logged, for logged message; sent, for outbound sent message; and received, for inbound sent message.
      msgCount Number Number of messages for which information was returned.
      countExceeded Boolean Indicates whether the number of messages that satisfies the search criteria exceeded the maximum allowed number of returned messages, and thus the returned result set had been truncated.

    Possible errors

    Status code Error message
    400 Device is deleted
    Device is not active
    Invalid parameters
    500 Internal server error
    503 System currently not available; please try again at a later time

    List Permission Events

    Retrieves a list of all system defined permission events.

    Sample request:

    GET /api/0.5/permission/events HTTP/1.1
    X-BCoT-Timestamp: 20180217T165054Z
    Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180217/ctn1_request, Signature=138e50e836dec8c78d48a46bd04c03434ff994b2cf59d929dff324e958f2c096
    Host: beta.catenis.io
    Connection: close
    User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
    
    curl "https://beta.catenis.io/api/0.5/permission/events" \
         -H 'X-BCoT-Timestamp: 20180217T170003Z' \
         -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180217/ctn1_request, Signature=d1f7556572b5f038563e997644a9682690c87fab6388ccbb16221ab4b72b3a56'
    
    <script src="CatenisAPIClientJS.min.js"></script>
    
    <script language="JavaScript">
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    ctnApiClient.listPermissionEvents(function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            Object.keys(data).forEach(function (eventName) {
                console.log('Event name:', eventName, '; event description:', data[eventName]);
            });
        }
    });
    </script>
    
    var CtnApiClient = require('catenis-api-client');
    
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    ctnApiClient.listPermissionEvents(function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            Object.keys(data).forEach(function (eventName) {
                console.log('Event name:', eventName, '; event description:', data[eventName]);
            });
        }
    });
    

    Request

    GET /permission/events

    Parameters

    This request does not take any parameters.

    Sample response:

    {
      "status": "success",
      "data": {
        "receive-notify-new-msg": "Receive notification of new message from a device",
        "receive-notify-msg-read": "Receive notification of message read by a device",
        "send-read-msg-confirm": "Send read message confirmation to a device",
        "receive-msg": "Receive message from a device",
        "disclose-main-props": "Disclose device's main properties (name, product unique ID) to a device",
        "disclose-identity-info": "Disclose device's basic identification information to a device"
      }
    }
    

    Success response

    A JSON containing the following properties:

    Property Type Description
    status String The value success, indicating that the request was successful.
    data Object The actual data returned in response to the API request. In this particular case, it is an object that works as a dictionary where its properties are the permission event names, and their respective values the permission event description.
      <event_name> String The description of the permission event whose name is this property's name.

    Possible errors

    Status code Error message
    500 Internal server error
    503 System currently not available; please try again at a later time

    Retrieve Permission Rights

    Gets the permission rights currently set for a specific permission event.

    The virtual device issuing the request acts as the controlling device. Thus the permission rights to be retrieved are the ones set for the pair composed of the permission event specified in the API request and the virtual device issuing the request.

    Sample request:

    GET /api/0.5/permission/events/receive-msg/rights HTTP/1.1
    X-BCoT-Timestamp: 20180217T193337Z
    Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180217/ctn1_request, Signature=b6bf27017c8ee92da349f80e27e127f3c2cb3adeeeee28e19c18d9b9c3b752a8
    Host: beta.catenis.io
    Connection: close
    User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
    
    curl "https://beta.catenis.io/api/0.5/permission/events/receive-msg/rights" \
         -H 'X-BCoT-Timestamp: 20180217T193358Z' \
         -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180217/ctn1_request, Signature=6d2748f961de6714c16a0ff9096a9a9c2607778c2dc107d2f7492bc0878d2a81'
    
    <script src="CatenisAPIClientJS.min.js"></script>
    
    <script language="JavaScript">
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    ctnApiClient.retrievePermissionRights('receive-msg', function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            console.log('Default (system) permission right:', data.system);
    
            if (data.catenisNode) {
                if (data.catenisNode.allow) {
                    console.log('Index of Catenis nodes with \'allow\' permission right:', data.catenisNode.allow);
                }
    
                if (data.catenisNode.deny) {
                    console.log('Index of Catenis nodes with \'deny\' permission right:', data.catenisNode.deny);
                }
            }
    
            if (data.client) {
                if (data.client.allow) {
                    console.log('ID of clients with \'allow\' permission right:', data.client.allow);
                }
    
                if (data.client.deny) {
                    console.log('ID of clients with \'deny\' permission right:', data.client.deny);
                }
            }
    
            if (data.device) {
                if (data.device.allow) {
                    console.log('Devices with \'allow\' permission right:', data.device.allow);
                }
    
                if (data.device.deny) {
                    console.log('Devices with \'deny\' permission right:', data.device.deny);
                }
            }
        }
    });
    </script>
    
    var CtnApiClient = require('catenis-api-client');
    
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    ctnApiClient.retrievePermissionRights('receive-msg', function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            console.log('Default (system) permission right:', data.system);
    
            if (data.catenisNode) {
                if (data.catenisNode.allow) {
                    console.log('Index of Catenis nodes with \'allow\' permission right:', data.catenisNode.allow);
                }
    
                if (data.catenisNode.deny) {
                    console.log('Index of Catenis nodes with \'deny\' permission right:', data.catenisNode.deny);
                }
            }
    
            if (data.client) {
                if (data.client.allow) {
                    console.log('ID of clients with \'allow\' permission right:', data.client.allow);
                }
    
                if (data.client.deny) {
                    console.log('ID of clients with \'deny\' permission right:', data.client.deny);
                }
            }
    
            if (data.device) {
                if (data.device.allow) {
                    console.log('Devices with \'allow\' permission right:', data.device.allow);
                }
    
                if (data.device.deny) {
                    console.log('Devices with \'deny\' permission right:', data.device.deny);
                }
            }
        }
    });
    

    Request

    GET /permission/events/:eventName/rights

    Parameters

    Sample response:

    {
      "status": "success",
      "data": {
        "system": "deny",
        "client": {
          "allow": [
            "cjNhuvGMUYoepFcRZadP"
          ]
        },
        "device": {
          "allow": [
            {
              "deviceId": "dv3htgvK7hjnKx3617Re",
              "name": "Catenis device #1"
            }
          ]
        }
      }
    }
    

    Success response

    A JSON containing the following properties:

    Property Type Description
    status String The value success, indicating that the request was successful.
    data Object The actual data returned in response to the API request.
      system String Permission right set at the system level.
      catenisNode Object (only returned if there are any permission rights set at the Catenis node level)
        allow Array(String) (only returned if not empty) List of Catenis node indices identifying the Catenis nodes to which allow right has been given.
        deny Array(String) (only returned if not empty) List of Catenis node indices identifying the Catenis nodes to which deny right has been given.
      client Object (only returned if there are any permission rights set at the client level)
        allow Array(String) (only returned if not empty) List of client IDs identifying the clients to which allow right has been given.
        deny Array(String) (only returned if not empty) List of client IDs identifying the clients to which deny right has been given.
      device Object (only returned if there are any permission rights set at the device level)
        allow Array(Object) (only returned if not empty) List of virtual device info objects identifying the devices to which allow right has been given.
          deviceId String The device ID of the virtual device.
          name String (only returned if virtual device has this data, and the virtual device issuing the request has the necessary permission right) The name of the virtual device.
          prodUniqueId String (only returned if virtual device has this data, and the virtual device issuing the request has the necessary permission right) The product unique ID of the virtual device.
        deny Array(Object) (only returned if not empty) List of virtual device info objects identifying the virtual devices to which deny right has been given.
          deviceId String The device ID of the virtual device.
          name String (only returned if virtual device has this data, and the virtual device issuing the request has the necessary permission right) The name of the virtual device.
          prodUniqueId String (only returned if virtual device has this data, and the virtual device issuing the request has the necessary permission right) The product unique ID of the virtual device.

    Possible errors

    Status code Error message
    400 Device is deleted
    Device is not active
    Invalid parameters
    500 Internal server error
    503 System currently not available; please try again at a later time

    Set Permission Rights

    Sets permission rights at different levels for a specific permission event.

    The virtual device issuing the request acts as the controlling device. Thus the permission rights are set for the pair composed of the permission event specified in the API request and the virtual device issuing the request.

    Sample request:

    POST /api/0.5/permission/events/receive-msg/rights HTTP/1.1
    X-BCoT-Timestamp: 20180217T201833Z
    Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180217/ctn1_request, Signature=df048c4f799dbc0b15b7b105313b9c134d499eb330ecf1ee2b27b5319c89bb86
    Content-Type: application/json; charset=utf-8
    Host: beta.catenis.io
    Connection: close
    User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
    Content-Length: 147
    
    {"client":{"allow":"self","deny":"cjNhuvGMUYoepFcRZadP"},"device":{"allow":[{"id":"dv3htgvK7hjnKx3617Re"},{"id":"XYZ0001","isProdUniqueId":true}]}}
    
    curl -X "POST" "https://beta.catenis.io/api/0.5/permission/events/receive-msg/rights" \
         -H 'X-BCoT-Timestamp: 20180217T201855Z' \
         -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180217/ctn1_request, Signature=d52d99ab524ee9f6ed7ca4d96c0041ff9ba7ca1540497dc527c51596da98a27a' \
         -H 'Content-Type: application/json; charset=utf-8' \
         -d $'{
      "client": {
        "allow": "self",
        "deny": "cjNhuvGMUYoepFcRZadP"
      },
      "device": {
        "allow": [
          {
            "id": "dv3htgvK7hjnKx3617Re"
          },
          {
            "id": "XYZ0001",
            "isProdUniqueId": true
          }
        ]
      }
    }'
    
    <script src="CatenisAPIClientJS.min.js"></script>
    
    <script language="JavaScript">
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    ctnApiClient.setPermissionRights('receive-msg', {
            client: {
                allow: 'self'
                deny: 'cjNhuvGMUYoepFcRZadP'
            },
            device: {
                allow: [{
                    id: 'dv3htgvK7hjnKx3617Re'
                }, {
                    id: 'XYZ0001',
                    isProdUniqueId: true
                }]
            }
        },
        function (err, data) {
            if (err) {
                // Process error
            }
            else {
                // Process returned data
                console.log('Permission rights successfully set');
            }
    });
    </script>
    
    var CtnApiClient = require('catenis-api-client');
    
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    ctnApiClient.setPermissionRights('receive-msg', {
            client: {
                allow: 'self'
                deny: 'cjNhuvGMUYoepFcRZadP'
            },
            device: {
                allow: [{
                    id: 'dv3htgvK7hjnKx3617Re'
                }, {
                    id: 'XYZ0001',
                    isProdUniqueId: true
                }]
            }
        },
        function (err, data) {
            if (err) {
                // Process error
            }
            else {
                // Process returned data
                console.log('Permission rights successfully set');
            }
    });
    

    Request

    POST /permission/events/:eventName/rights

    Parameters

    A JSON containing the following properties:

    Property Type Description
    system String (optional) Permission right to be set at the system level. Valid options: allow, deny.
    catenisNode Object (optional) Permission rights to be set at the Catenis node level.
      allow String|Array(String) (optional) A single Catenis node index or a list of Catenis node indices identifying the Catenis nodes to which allow right should be given. The special value self can be used in place of the index of the Catenis node where the client to which the virtual device issuing the request belongs is defined.
      deny String|Array(String) (optional) A single Catenis node index or a list of Catenis node indices identifying the Catenis nodes to which deny right should be given. The special value self can be used in place of the index of the Catenis node where the client to which the virtual device issuing the request belongs is defined.
      none String|Array(String) (optional) A single Catenis node index or a list of Catenis node indices identifying the Catenis nodes the rights of which should be removed. The special value self can be used in place of the index of the Catenis node where the client to which the virtual device issuing the request belongs is defined. The special wildcard character * can also be used to indicate that the rights for all Catenis nodes should be remove.
    client Object (optional) Permission rights to be set at the client level.
      allow String|Array(String) (optional) A single client ID or a list of client IDs identifying the clients to which allow right should be given. The special value self can be used in place of the client ID of the client to which the virtual device issuing the request belongs.
      deny String|Array(String) (optional) A single client ID or a list of client IDs identifying the clients to which deny right should be given. The special value self can be used in place of the client ID of the client to which the virtual device issuing the request belongs.
      none String|Array(String) (optional) A single client ID or a list of client IDs identifying the clients the rights of which should be removed. The special value self can be used in place of the client ID of the client to which the virtual device issuing the request belongs. The special wildcard character * can also be used to indicate that the rights for all clients should be remove.
    device Object (optional) Permission rights to be set at the device level.
      allow Object|Array(Object) (optional) A single virtual device info object or a list of virtual device info objects identifying the virtual devices to which allow right should be given.
        id String (optional) The ID of the virtual device. Should be a device ID unless isProdUniqueId is set. The special value self can be used in place of the device ID of the virtual device issuing the request.
        isProdUniqueId Boolean (optional, default: false) Indicates whether the supplied ID is a product unique ID.
      deny Object|Array(Object) (optional) A single virtual device info object or a list of virtual device info objects identifying the virtual devices to which deny right should be given.
        id String (optional) The ID of the virtual device. Should be a device ID unless isProdUniqueId is set. The special value self can be used in place of the device ID of the virtual device issuing the request.
        isProdUniqueId Boolean (optional, default: false) Indicates whether the supplied ID is a product unique ID.
      none Object|Array(Object) (optional) A single virtual device info object or a list of virtual device info objects identifying the virtual devices the rights of which should be removed.
        id String (optional) The ID of the virtual device. Should be a device ID unless isProdUniqueId is set. The special value self can be used in place of the device ID of the virtual device issuing the request. The special wildcard character * can also be used to indicate that the rights for all devices should be remove.
        isProdUniqueId Boolean (optional, default: false) Indicates whether the supplied ID is a product unique ID.

    Sample response:

    {
      "status": "success",
      "data": {
        "success": true
      }
    }
    

    Success response

    A JSON containing the following properties:

    Property Type Description
    status String The value success, indicating that the request was successful.
    data Object The actual data returned in response to the API request.
      success String The value true indicating that the permission rights have been correctly set.

    Possible errors

    Status code Error message
    400 Device is deleted
    Device is not active
    Invalid parameters
    Invalid entity ID: [ctnNodeIdx: …][; clientId: …][; deviceId: …][; prodUniqueId: …]
    500 Internal server error
    503 System currently not available; please try again at a later time

    Check Effective Permission Right

    Checks the effective permission right that is currently applied to a given virtual device for a specified permission event.

    The virtual device issuing the request acts as the controlling device. Thus the permission right returned is for the pair composed of the permission event specified in the API request and the virtual device issuing the request.

    Sample request:

    GET /api/0.5/permission/events/receive-msg/rights/dv3htgvK7hjnKx3617Re HTTP/1.1
    X-BCoT-Timestamp: 20180219T104640Z
    Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180219/ctn1_request, Signature=0753e60d70a02448386d6485ab6d7ca34b1faa851bf71b6219256ae5059dfa09
    Host: beta.catenis.io
    Connection: close
    User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
    
    curl "https://beta.catenis.io/api/0.5/permission/events/receive-msg/rights/dv3htgvK7hjnKx3617Re" \
         -H 'X-BCoT-Timestamp: 20180219T104602Z' \
         -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180219/ctn1_request, Signature=521537ae60e0cc6099c459220702aad51d68c7c6d82328d6df3d3dc122de8683'
    
    <script src="CatenisAPIClientJS.min.js"></script>
    
    <script language="JavaScript">
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    var checkDeviceId = 'dv3htgvK7hjnKx3617Re';
    
    ctnApiClient.checkEffectivePermissionRight('receive_msg', checkDeviceId, false, function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            var deviceId = Object.keys(data)[0];
    
            console.log('Effective right for device', deviceId, ':', data[deviceId]);
        }
    });
    </script>
    
    var CtnApiClient = require('catenis-api-client');
    
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    var checkDeviceId = 'dv3htgvK7hjnKx3617Re';
    
    ctnApiClient.checkEffectivePermissionRight('receive_msg', checkDeviceId, false, function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            var deviceId = Object.keys(data)[0];
    
            console.log('Effective right for device', deviceId, ':', data[deviceId]);
        }
    });
    

    Request

    GET /permission/events/:eventName/rights/:deviceId

    Parameters

    Sample response:

    {
      "status": "success",
      "data": {
        "dv3htgvK7hjnKx3617Re": "allow"
      }
    }
    

    Success response

    A JSON containing the following properties:

    Property Type Description
    status String The value success, indicating that the request was successful.
    data Object The actual data returned in response to the API request. In this particular case, it is an object that works as a dictionary where its single property is the device ID of the device for which the effective permission right is being checked, and its value is the permission right itself.
      <check_device_ID> String The permission right that is currently in effective for the virtual device the device ID of which is this property's name.

    Possible errors

    Status code Error message
    400 Device is deleted
    Device is not active
    Invalid device
    Invalid parameters
    500 Internal server error
    503 System currently not available; please try again at a later time

    Retrieve Device Identification Info

    Gets the identification information of a given virtual device.

    Sample request:

    GET /api/0.5/devices/dv3htgvK7hjnKx3617Re HTTP/1.1
    X-BCoT-Timestamp: 20180219T133757Z
    Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180219/ctn1_request, Signature=ff2a8f3d8dc232d60208dc28f668351234ed25ead274e820ac081a480a275012
    Host: beta.catenis.io
    Connection: close
    User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
    
    curl "https://beta.catenis.io/api/0.5/devices/dv3htgvK7hjnKx3617Re" \
         -H 'X-BCoT-Timestamp: 20180219T133846Z' \
         -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180219/ctn1_request, Signature=74b0618fe8fe40278b3325cccdac350bed538a5faac86689c3d07e3f1df085f0'
    
    <script src="CatenisAPIClientJS.min.js"></script>
    
    <script language="JavaScript">
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    var checkDeviceId = 'dv3htgvK7hjnKx3617Re';
    
    ctnApiClient.retrieveDeviceIdentificationInfo(checkDeviceId, false, function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            console.log('Device\'s Catenis node ID info:', data.catenisNode);
            console.log('Device\'s client ID info:', data.client);
            console.log('Device\'s own ID info:', data.device);
        }
    });
    </script>
    
    var CtnApiClient = require('catenis-api-client');
    
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    var checkDeviceId = 'dv3htgvK7hjnKx3617Re';
    
    ctnApiClient.retrieveDeviceIdentificationInfo(checkDeviceId, false, function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            console.log('Device\'s Catenis node ID info:', data.catenisNode);
            console.log('Device\'s client ID info:', data.client);
            console.log('Device\'s own ID info:', data.device);
        }
    });
    

    Request

    GET /devices/:deviceId

    Parameters

    Sample response:

    {
      "status": "success",
      "data": {
        "catenisNode": {
          "ctnNodeIndex": 0,
          "name": "Catenis Hub",
          "description": "Central Catenis node used to house clients that access the system through the Internet"
        },
        "client": {
          "clientId": "cjNhuvGMUYoepFcRZadP",
          "name": "My test client"
        },
        "device": {
          "deviceId": "dv3htgvK7hjnKx3617Re",
          "name": "Catenis device #1"
        }
      }
    }
    

    Success response

    A JSON containing the following properties:

    Property Type Description
    status String The value success, indicating that the request was successful.
    data Object The actual data returned in response to the API request.
      catenisNode Object Information about the Catenis node where the client to which the specified virtual device belongs is defined.
        ctnNodeIndex Number The index of the Catenis node.
        name String (only returned if Catenis node has this data) The name of the Catenis node.
        description String (only returned if Catenis node has this data) A short description about the Catenis node.
      client Object Information about the client to which the specified virtual device belongs.
        clientId String The client ID of the client.
        name String (only returned if client has this data) The name of the client.
      device Object Information about the specified virtual device itself.
        deviceId String The device ID of the virtual device.
        name String (only returned if virtual device has this data) The name of the virtual device.
        prodUniqueId String (only returned if virtual device has this data) The product unique ID of the virtual device.

    Possible errors

    Status code Error message
    400 Device is deleted
    Device is not active
    Invalid device
    Invalid parameters
    403 No permission to retrieve info
    500 Internal server error
    503 System currently not available; please try again at a later time

    List Notification Events

    Retrieves a list of all system defined notification events.

    Sample request:

    GET /api/0.5/notification/events HTTP/1.1
    X-BCoT-Timestamp: 20180219T160411Z
    Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180219/ctn1_request, Signature=02e8f56a46e2ea8001f94fac04115749606deacd5eee6f553b6d69c5d45ce553
    Host: beta.catenis.io
    Connection: close
    User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
    
    curl "https://beta.catenis.io/api/0.5/notification/events" \
         -H 'X-BCoT-Timestamp: 20180219T160346Z' \
         -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180219/ctn1_request, Signature=7b717edae1c2c60721e2f74d02feb286a2275f615c930d86f5ea9954214bdfaf'
    
    <script src="CatenisAPIClientJS.min.js"></script>
    
    <script language="JavaScript">
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    ctnApiClient.listNotificationEvents(function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            Object.keys(data).forEach(function (eventName) {
                console.log('Event name:', eventName, '; event description:', data[eventName]);
            });
        }
    });
    </script>
    
    var CtnApiClient = require('catenis-api-client');
    
    var deviceId = 'dnN3Ea43bhMTHtTvpytS';
    
    var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
        environment: 'beta'
    });
    
    ctnApiClient.listNotificationEvents(function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            Object.keys(data).forEach(function (eventName) {
                console.log('Event name:', eventName, '; event description:', data[eventName]);
            });
        }
    });
    

    Request

    GET /notification/events

    Parameters

    This request does not take any parameters.

    Sample response:

    {
      "status": "success",
      "data": {
        "new-msg-received": "A new message has been received",
        "sent-msg-read": "Previously sent message has been read by intended receiver (target device)"
      }
    }
    

    Success response

    A JSON containing the following properties:

    Property Type Description
    status String The value success, indicating that the request was successful.
    data Object The actual data returned in response to the API request. In this particular case, it is an object that works as a dictionary where its properties are the notification event names, and their respective values the notification event description.
      <event_name> String The description of the notification event whose name is this property's name.

    Possible errors

    Status code Error message
    500 Internal server error
    503 System currently not available; please try again at a later time

    Notifications

    Catenis Enterprise provides a notification mechanism where a virtual device can receive a real-time message notifying that a given predefined event that concerns it has taken place. Such predefined events are referred to as notification events.

    Notification events

    The following notification events are currently defined:

    Event name Description
    new-msg-received A new message has been received
    sent-msg-read Previously sent message has been read by intended receiver (target device)

    Notification messages

    The Catenis Enterprise notifications are conveyed by means of notification messages the contents of which vary according to the notification event, as follows:

    New message received (new-msg-received)

    Sample notification message:

    {
      "messageId": "mNEWqgSMAeDAmBAkBDWr",
      "from": {
        "deviceId": "dnN3Ea43bhMTHtTvpytS",
        "name": "deviceB",
        "prodUniqueId": "XYZABC001"
      },
      "receivedDate": "2018-01-29T23:27:39.657Z"
    }
    

    A JSON containing the following properties:

    Property Type Description
    messageId String The ID of the received message.
    from Object Identifies the virtual device that sent the received message — the origin device.
      deviceId String The device ID of the origin device.
      name String (only returned if origin device has this data, and the device receiving the notification has the necessary permission right) The name of the origin device.
      prodUniqueId String (only returned if origin device has this data, and the device receiving the notification has the necessary permission right) The product unique ID of the origin device.
    receivedDate String ISO 8601 formatted date and time when the message has been received.

    Sent message read (sent-msg-read)

    Sample notification message:

    {
      "messageId": "mNEWqgSMAeDAmBAkBDWr",
      "to": {
        "deviceId": "dv3htgvK7hjnKx3617Re",
        "name": "Catenis device #1"
      },
      "readDate": "2018-01-30T01:02:12.162Z"
    }
    

    A JSON containing the following properties:

    Property Type Description
    messageId String The ID of the read message.
    to Object Identifies the device to which the read message had been sent — the target device.
      deviceId String The device ID of the target device.
      name String (only returned if target device has this data, and the device receiving the notification has the necessary permission right) The name of the target device.
      prodUniqueId String (only returned if target device has this data, and the device receiving the notification has the necessary permission right) The product unique ID of the target device.
    readDate String ISO 8601 formatted date and time when the message has been read.

    Notification channel

    To be able to receive notifications, a virtual device must open a notification channel for a specific notification event. Then, as long as the notification channel is open, the virtual device shall receive notification messages when the corresponding event takes place.

    The way that a notification channel is open depends on the notification transport that the notification channel uses.

    The following notification transports are currently provided:

    WebSocket notification channel

    URL (beta environment)

    wss://beta.catenis.io/api/notify/ws/:eventName

    WebSocket subprotocol

    notify.catenis.io

    Parameters

    Authentication

    The following steps should be taken in order to successfully authenticate the virtual device when opening a WebSocket notification channel:

    Sample authenticated dummy WebSocket notification request:

    GET /api/notify/ws/new-msg-received HTTP/1.1
    X-BCoT-Timestamp: 20180219T223932Z
    Authorization: CTN1-HMAC-SHA256 Credential=dmM2Dz32agLSGsSuoxsR/20180219/ctn1_request, Signature=59b44f3d504b272e92c1f96694b7f6abb39b8cb7726ffe8b57d2cb46aedf568b
    Host: beta.catenis.io
    Connection: close
    User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
    

    Sample WebSocket authentication message:

    {
      "x-bcot-timestamp": "20180219T223932Z",
      "authorization": "CTN1-HMAC-SHA256 Credential=dmM2Dz32agLSGsSuoxsR/20180219/ctn1_request, Signature=59b44f3d504b272e92c1f96694b7f6abb39b8cb7726ffe8b57d2cb46aedf568b"
    }
    
    1. Assemble a dummy GET request using the WebSocket notification channel URL, and then authenticate it as if it was a regular Catenis API request — for more information about API request authentication, please refer to the Authentication section above.

    2. Do not send the authenticated request, but rather just take the HTTP headers X-BCoT-Timestamp and Authorization contained in it and save them.

    3. Go ahead and open the WebSocket connection.

    4. Right after the WebSocket connection is open, send a single message the contents of which should be a JSON containing the following properties:

    Property Type Description
    x-bcot-timestamp String The value of the X-BCoT-Timestamp HTTP header saved at step 3 above.
    authorization String The value of the Authorization HTTP header saved at step 3 above.

    Errors

    Catenis Enterprise uses conventional HTTP response status codes to indicate the general outcome of an API request.

    HTTP status codes

    The following HTTP status codes are returned by the Catenis Enterprise API.

    Status code Explanation
    200 OK - The request succeeded.
    400 Bad Request - The request could not be processed the way it was, and should be changed before it is resubmitted.
    401 Unauthorized - The request requires user authentication, or authorization has been refused for the supplied credentials.
    403 Forbidden - The request cannot be fulfilled.
    500 Internal Server Error - The server encountered an unexpected condition which prevented it from fulfilling the request.
    503 Service Unavailable - The server is currently unable to handle the request.

    Error response

    Error response:

    {
      "status": "error",
      "message": "Invalid parameters"
    }
    

    To better describe the condition that led to the error, a JSON with the following properties is returned for all failed API requests.

    Property Type Description
    status String The value error, indicating that the request has failed.
    message String Error message

    Error messages

    The following is a comprehensive list of the error messages returned by the Catenis Enterprise API.

    Error message Explanation
    Authorization failed; authorization value not well formed Request could not be authorized because the contents of the Authorization HTTP header is not as expected.
    Authorization failed; invalid device or signature Request could not be authorized because the device ID and/or the signature included in the credentials (Authorization header contents) are not valid.
    Authorization failed; missing required HTTP headers Request could not be authorized because one or more of the required HTTP headers are missing.
    Authorization failed; signature date not well formed Request could not be authorized because the format of the date included in the credentials (Authorization header contents) is not correct.
    Authorization failed; signature date out of bounds Request could not be authorized because the date included in the credentials (Authorization header contents) is not within 7 days of the current date.
    Authorization failed; timestamp not well formed Request could not be authorized because the contents of the X-BCoT-Timestamp HTTP header is not a valid timestamp or it is not in the correct format.
    Authorization failed; timestamp not within acceptable time variation Request could not be authorized because its timestamp (X-BCoT-Timestamp header contents) is not within +/-5 minutes of the current Catenis Enterprise server time.
    Device is deleted Virtual device no longer exists as it has been deleted.
    Device is not active Virtual device is not yet ready to be used.
    Internal server error An unexpected situation prevented Catenis Enterprise from correctly processing the request.
    Invalid device The ID (either the device ID or the product unique ID) for the specified virtual device is not valid or there is no virtual device with that ID.
    Invalid message ID The supplied message ID is invalid or no message with that ID could be found.
    Invalid parameters One or more of the parameters are not well formed or required parameter is missing.
    Invalid target device The ID (either the device ID or the product unique ID) for the virtual device to receive the message is not valid or there is no virtual device with that ID.
    Message too long to be embedded Request specified that message should be stored embedded in the blockchain transaction but it is too large (over 75 bytes unencrypted or 64 bytes encrypted) to fit in.
    No credit to log message The client service account balance is too low to cover the log message service's expense.
    No credit to send message The client service account balance is too low to cover the send message service's expense.
    No permission to read message Virtual device has no permission to read the requested message.
    No permission to retrieve info Virtual device has no permission to retrieve information about the requested device.
    No permission to retrieve message container Virtual device attempting to retrieve the message container information is not the device who sent/logged the message.
    Invalid entity ID: [ctnNodeIdx: …][; clientId: …][; deviceId: …][; prodUniqueId: …] One or more of the supplied entity IDs (Catenis Node index, client ID, device ID, or product unique ID) are not valid or there are no entities (Catenis Node, client, or virtual device) with those IDs.
    System currently not available; please try again at a later time Catenis Enterprise is not currently ready to process requests.