NAV Navbar
Raw Shell JavaScript Node.js PHP C++

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

The Catenis Enterprise API ver. 0.6 is available in the following environments.

Sandbox

This is a non-production environment that connects with the testnet Bitcoin network.

Base API URL

https://sandbox.catenis.io/api/0.6/

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
receive-notify-asset-of Receive notification of asset received for assets issued by a device
receive-notify-asset-from Receive notification of asset received from a device
receive-notify-confirm-asset-of Receive notification of confirmation of pending asset issued by a device
receive-notify-confirm-asset-from Receive notification of confirmation of pending asset transferred 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
receive-asset-of Receive an amount of an asset issued by a device
receive-asset-from Receive an amount of an asset from 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.6/messages/log HTTP/1.1
Host: sandbox.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: sandbox.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.6/message/send\nhost:api.catenis.com\nx-bcot-timestamp:20180127T121358Z\n\n792cdbeef04dc33e8ebb4974070ec5a75bd1e3a6c5ef49b1c3ec1b87152694c6\n"

Printed text:

  POST
  api/0.6/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.6/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:sandbox.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.6/messages/log HTTP/1.1
Host: sandbox.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 that comprise the Catenis Enterprise API ver. 0.6.

Log Message

Records a message on the blockchain.

Sample request:

POST /api/0.6/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: sandbox.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://sandbox.catenis.io/api/0.6/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: 'sandbox'
});

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: 'sandbox'
});

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);
        }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

try {
    $data = $ctnApiClient->logMessage('This is only a test', [
        'encoding' => 'utf8',
        'encrypt' => true,
        'storage' => 'auto'
    ]);

    // Process returned data
    echo 'ID of logged message: ' . $data->messageId . PHP_EOL;
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

ctn::LogMessageResult data;
ctn::MessageOptions msgOpts("utf8", true, "auto");

try {
    ctnApiClient.logMessage(data, "My message", msgOpts);

    std::cout << "ID of logged message: " << data.messageId << std::endl;
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::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
Not enough credits to pay for log message service
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.6/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: sandbox.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://sandbox.catenis.io/api/0.6/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: 'sandbox'
});

var targetDevice = {
    id: 'dv3htgvK7hjnKx3617Re'
}

ctnApiClient.sendMessage(targetDevice, 'This is only a test', {
        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: 'sandbox'
});

var targetDevice = {
    id: 'dv3htgvK7hjnKx3617Re'
}

ctnApiClient.sendMessage(targetDevice, 'This is only a test', {
        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);
        }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

$targetDevice = [
  'id' => 'dv3htgvK7hjnKx3617Re'
];

try {
    $data = $ctnApiClient->sendMessage($targetDevice, 'My message to send', [
        'readConfirmation' => true,
        'encoding' => 'utf8',
        'encrypt' => true,
        'storage' => 'auto'
    ]);

    // Process returned data
    echo 'ID of sent message: ' . $data->messageId . PHP_EOL;
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

ctn::SendMessageResult data;
ctn::Device targetDevice("dv3htgvK7hjnKx3617Re");
ctn::MessageOptions msgOpts("utf8", true, "auto", true);

try {
    client.sendMessage(data, targetDevice, "My message to send", msgOpts);

    std::cout << "ID of sent message: " << data.messageId << std::endl;
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::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
Not enough credits to pay for send message service
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.6/messages/mDWPuD5kjCsEiNEEWwrW?encoding=utf8 HTTP/1.1
X-BCoT-Timestamp: 20180215T112048Z
Authorization: CTN1-HMAC-SHA256 Credential=dmM2Dz32agLSGsSuoxsR/20180215/ctn1_request, Signature=10b1299fdf935544b44e3e1e8de7d3f3df03df9ddc35db0127d5ab0cafa36cbb
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.6/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: 'sandbox'
});

var messageId = 'mDWPuD5kjCsEiNEEWwrW';

ctnApiClient.readMessage(messageId, 'utf8', function (err, data) {
    if (err) {
        // Process error
    }
    else {
        // Process returned data
        console.log('Read message:', data.message);

        if (data.action === 'send') {
            console.log('Message set from:', data.from);
        }
    }
});
</script>
var CtnApiClient = require('catenis-api-client');

var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

var messageId = 'mDWPuD5kjCsEiNEEWwrW';

ctnApiClient.readMessage(messageId, 'utf8', function (err, data) {
    if (err) {
        // Process error
    }
    else {
        // Process returned data
        console.log('Read message:', data.message);

        if (data.action === 'send') {
            console.log('Message sent from:', data.from);
        }
    }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

$messageId = 'mDWPuD5kjCsEiNEEWwrW';

try {
    $data = $ctnApiClient->readMessage($messageId, 'utf8');

    // Process returned data
    echo 'Read message: ' . $data->message . PHP_EOL;

    if ($data->action === 'send') {
        echo 'Message sent from: ' . print_r($data->from, true);
    }
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

ctn::ReadMessageResult data;
std::string message_id("mDWPuD5kjCsEiNEEWwrW");

try {
    client.readMessage(data, message_id, "utf8");

    std::cout << "Message read: " << data.message << endl;

    if (data.action == "send"} {
        std::cout << "Message sent from (device ID): " << data.from->deviceId;
    }
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::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.6/messages/mDWPuD5kjCsEiNEEWwrW/container HTTP/1.1
X-BCoT-Timestamp: 20180215T200325Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180215/ctn1_request, Signature=f06dc359270c2a3a91326ef2e7fd5506fd75dc9740b2609ed796ce01b3f92afb
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.6/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: 'sandbox'
});

var messageId = 'mDWPuD5kjCsEiNEEWwrW';

ctnApiClient.retrieveMessageContainer(messageId, function (err, data) {
    if (err) {
        // Process error
    }
    else {
        // Process returned data
        console.log('ID of blockchain transaction containing the message:', data.blockchain.txid);

        if (data.externalStorage) {
            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: 'sandbox'
});

var messageId = 'mDWPuD5kjCsEiNEEWwrW';

ctnApiClient.retrieveMessageContainer(messageId, function (err, data) {
    if (err) {
        // Process error
    }
    else {
        // Process returned data
        console.log('ID of blockchain transaction containing the message:', data.blockchain.txid);

        if (data.externalStorage) {
            console.log('IPFS reference to message:', data.externalStorage.ipfs);
        }
    }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

$messageId = 'mDWPuD5kjCsEiNEEWwrW';

try {
    $data = $ctnApiClient->retrieveMessageContainer($messageId);

    // Process returned data
    echo 'ID of blockchain transaction containing the message: ' . $data->blockchain->txid . PHP_EOL;

    if (isset($data->externalStorage)) {
        echo 'IPFS reference to message: ' . $data->externalStorage->ipfs;
    }
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

ctn::RetrieveMessageContainerResult data;
std::string message_id("mDWPuD5kjCsEiNEEWwrW");

try {
    client.retrieveMessageContainer(data, message_id);

    std::cout << "ID of blockchain transaction containing the message: " << data.blockchain.txid << endl;

    if (data.externalStorage != nullptr) {
       std::cout << "IPFS reference to message: " << (*data.externalStorage)["ipfs"] << endl;
    }
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::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.6/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: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.6/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: 'sandbox'
});

ctnApiClient.listMessages({
        action: 'send',
        direction: 'inbound',
        fromDevices: [{
            id: '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: 'sandbox'
});

ctnApiClient.listMessages({
        action: 'send',
        direction: 'inbound',
        fromDevices: [{
            id: '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!';
                }
            }
        }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

try {
    $data = $ctnApiClient->listMessages([
        'action' => 'send',
        'direction' => 'inbound',
        'fromDevices' => [[
            'id' => 'dv3htgvK7hjnKx3617Re'
        ]],
        'readState' => 'unread',
        'startDate' => '20180101T000000Z',
        'endDate' => '20180228T235959Z'
    ]);

    // Process returned data
    if ($data->msgCount > 0) {
        echo 'Returned messages: ' . print_r($data->messages, true);

        if ($data->countExceeded) {
            echo 'Warning: not all messages fulfilling search criteria have been returned!' . PHP_EOL;
        }
    }
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

ctn::ListMessagesResult data;

try {
    client.listMessages(data, "send", "inbound", "dv3htgvK7hjnKx3617Re", "", "", "", "unread", "20180101T000000Z", "20180228T235959Z");

    int msgCounter = 0;

    for (auto it = data.messageList.begin(); it != data.messageList.end(); it++) {
        std::cout << "Message #" << ++msgCounter << ":" << std::endl;

        std::shared_ptr<ctn::MessageDescription> msgDesc = *it;

        std::cout << "  message ID: " << msgDesc->messageId << std::endl;
        std::cout << "  action: " << msgDesc->action << std::endl;

        // Process further message info appropriately
    }

    if (data.countExceeded) {
        std::cout << "Warning: not all messages fulfilling search criteria have been returned!" << std::endl;
    }
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::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": "Catenis device #1"
        },
        "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

Issue Asset

Issues an amount of a new asset.

Sample request:

POST /api/0.6/assets/issue/ HTTP/1.1
X-BCoT-Timestamp: 20180416T192026Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180416/ctn1_request, Signature=ca4df849242d5b66c45d24c3dd2f8810f7063f4bf1df1555aa95d18405b7b5dd
Content-Type: application/json; charset=utf-8
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
Content-Length: 114

{"assetInfo":{"name":"XYZ001","description":"Testing asset #1","canReissue":true,"decimalPlaces":2},"amount":1200}
curl -X "POST" "https://sandbox.catenis.io/api/0.6/assets/issue/" \
     -H 'X-BCoT-Timestamp: 20180416T191501Z' \
     -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180416/ctn1_request, Signature=fd75cb18eb60c6afa8c5be53dadf1937b08c131d39b20fce19badb285bdb79cc' \
     -H 'Content-Type: application/json; charset=utf-8' \
     -d $'{
  "amount": 1200,
  "assetInfo": {
    "decimalPlaces": 2,
    "name": "XYZ001",
    "description": "Testing asset #1",
    "canReissue": true
  }
}'
<script src="CatenisAPIClientJS.min.js"></script>

<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

ctnApiClient.issueAsset({
        name: 'XYZ001'
        description: 'Testing asset #1'
        canReissue: true
        decimalPlaces: 2
    }, 1200.00, null,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            console.log('ID of newly issued asset:', data.assetId);
        }
});
</script>
var CtnApiClient = require('catenis-api-client');

var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

ctnApiClient.issueAsset({
        name: 'XYZ001'
        description: 'Testing asset #1'
        canReissue: true
        decimalPlaces: 2
    }, 1200.00, null,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            console.log('ID of newly issued asset:', data.assetId);
        }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

try {
    $data = $ctnApiClient->issueAsset([
        'name' => 'XYZ001',
        'description' => 'Testing asset #1',
        'canReissue' => true,
        'decimalPlaces' => 2
    ], 1200.00, null);

    // Process returned data
    echo 'ID of newly issued asset: ' . $data->assetId . PHP_EOL;
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

// TODO: complete source code

try {
    // TODO: complete source code
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::endl;
}

Request

POST /assets/issue

Parameters

A JSON containing the following properties:

Property Type Description
assetInfo Object
  name String The name of the asset to create.
  description String (optional) A description of the asset to create.
  canReissue Boolean Indicates whether more units of this asset can be issued at another time.
  decimalPlaces Number The maximum number of decimal places that can be used to specify a fractional amount of this asset.
amount Number The amount of asset to issue.
holdingDevice Object (optional) Virtual device for which the asset is issued and that shall hold the issued amount.
  id String The ID of the holding device. Should be a device ID unless isProdUniqueId is set.
  isProdUniqueId Boolean (optional, default: false) Indicates whether the supplied ID is a product unique ID.

Sample response:

{
  "status": "success",
  "data": {
    "assetId": "aQjlzShmrnEZeeYBZihc"
  }
}

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.
  assetId String ID of the newlly issued asset.

Possible errors

Status code Error message
400 Amount to issue is too large
Device is deleted
Device is not active
Invalid holding device
Invalid parameters
Not enough credits to pay for issue asset service
403 No permission to assign issued asset to holding device
500 Internal server error
503 System currently not available; please try again at a later time

Reissue Asset

Issues an additional amount of an existing asset.

Sample request:

POST /api/0.6/assets/aQjlzShmrnEZeeYBZihc/issue/ HTTP/1.1
X-BCoT-Timestamp: 20180417T004201Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=71d61d674882e0bcfadcda962cf3393b300af6f0cbbc5fb211f1f33d5bbd8b3a
Content-Type: application/json; charset=utf-8
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
Content-Length: 60

{"amount":450,"holdingDevice":{"id":"dv3htgvK7hjnKx3617Re"}}
curl -X "POST" "https://sandbox.catenis.io/api/0.6/assets/aQjlzShmrnEZeeYBZihc/issue/" \
     -H 'X-BCoT-Timestamp: 20180417T004241Z' \
     -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=bfed2a3062c5ee48623ff863d5bc5bedee85189303617be7b01b080c8d9ca950' \
     -H 'Content-Type: application/json; charset=utf-8' \
     -d $'{
  "amount": 450,
  "holdingDevice": {
    "id": "dv3htgvK7hjnKx3617Re"
  }
}'
<script src="CatenisAPIClientJS.min.js"></script>

<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

var assetId = 'aQjlzShmrnEZeeYBZihc';
var holdingDevice = {
    id: 'dv3htgvK7hjnKx3617Re'
};

ctnApiClient.reissueAsset(assetId, 450.00, holdingDevice,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            console.log('Total existent asset balance (after issuance):', data.totalExistentBalance);
        }
});
</script>
var CtnApiClient = require('catenis-api-client');

var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

var assetId = 'aQjlzShmrnEZeeYBZihc';
var holdingDevice = {
    id: 'dv3htgvK7hjnKx3617Re'
};

ctnApiClient.reissueAsset(assetId, 450.00, holdingDevice,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            console.log('Total existent asset balance (after issuance):', data.totalExistentBalance);
        }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

$assetId = 'aQjlzShmrnEZeeYBZihc';
$holdingDevice = [
   'id' => 'dv3htgvK7hjnKx3617Re'
];

try {
    $data = $ctnApiClient->reissueAsset($assetId, 450.00, $holdingDevice);

    // Process returned data
    echo 'Total existent asset balance (after issuance): ' . $data->totalExistentBalance . PHP_EOL;
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

// TODO: complete source code

try {
    // TODO: complete source code
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::endl;
}

Request

POST /assets/:assetId/issue

Parameters

A JSON containing the following properties:

Property Type Description
amount Number The amount of asset to issue.
holdingDevice Object (optional) Virtual device for which the asset is issued and that shall hold the issued amount.
  id String The ID of the holding device. Should be a device ID unless isProdUniqueId is set.
  isProdUniqueId Boolean (optional, default: false) Indicates whether the supplied ID is a product unique ID.

Sample response:

{
  "status": "success",
  "data": {
    "totalExistentBalance": 1650
  }
}

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.
  totalExistentBalance Number Total balance of the asset in existence after specified amount has been issued.

Possible errors

Status code Error message
400 Amount to issue is too large
Asset cannot be reissued
Device is deleted
Device is not active
Invalid asset ID
Invalid holding device
Invalid parameters
Not enough credits to pay for issue asset service
403 No permission to reissue asset
500 Internal server error
503 System currently not available; please try again at a later time

Transfer Asset

Transfers an amount of an asset to a device.

Sample request:

POST /api/0.6/assets/aQjlzShmrnEZeeYBZihc/transfer/ HTTP/1.1
X-BCoT-Timestamp: 20180417T132059Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=44e21bb5c895eceafce0910a27d0879e3be7dcff278c07a01597f09e6c0bb317
Content-Type: application/json; charset=utf-8
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
Content-Length: 64

{"amount":54.25,"receivingDevice":{"id":"dv3htgvK7hjnKx3617Re"}}
curl -X "POST" "https://sandbox.catenis.io/api/0.6/assets/aQjlzShmrnEZeeYBZihc/transfer/" \
     -H 'X-BCoT-Timestamp: 20180417T132027Z' \
     -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=17bb4e914bd10aa517d15df1c985f0e9604a660a3a146219e16a1c94a8f7bf93' \
     -H 'Content-Type: application/json; charset=utf-8' \
     -d $'{
  "amount": 54.25,
  "receivingDevice": {
    "id": "dv3htgvK7hjnKx3617Re"
  }
}'
<script src="CatenisAPIClientJS.min.js"></script>

<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

var assetId = 'aQjlzShmrnEZeeYBZihc';
var receivingDevice = {
    id: 'dv3htgvK7hjnKx3617Re'
}

ctnApiClient.transferAsset(assetId, 54.25, receivingDevice,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            console.log('Remaining asset balance:', data.remainingBalance);
        }
});
</script>
var CtnApiClient = require('catenis-api-client');

var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

var assetId = 'aQjlzShmrnEZeeYBZihc';
var receivingDevice = {
    id: 'dv3htgvK7hjnKx3617Re'
}

ctnApiClient.transferAsset(assetId, 54.25, receivingDevice,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            console.log('Remaining asset balance:', data.remainingBalance);
        }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

$assetId = 'aQjlzShmrnEZeeYBZihc';
$receivingDevice = [
   'id' => 'dv3htgvK7hjnKx3617Re'
];

try {
    $data = $ctnApiClient->transferAsset($assetId, 54.25, $receivingDevice);

    // Process returned data
    echo 'Remaining asset balance: ' . $data->remainingBalance . PHP_EOL;
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

// TODO: complete source code

try {
    // TODO: complete source code
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::endl;
}

Request

POST /assets/:assetId/transfer

Parameters

A JSON containing the following properties:

Property Type Description
amount Number The amount of asset to transfer.
receivingDevice Object Virtual device to which the asset is to be transferred.
  id String The ID of the receiving device. Should be a device ID unless isProdUniqueId is set.
  isProdUniqueId Boolean (optional, default: false) Indicates whether the supplied ID is a product unique ID.

Sample response:

{
  "status": "success",
  "data": {
    "remainingBalance": 1145.75
  }
}

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.
  remainingBalance Number Total balance of the asset still held by the device that issued the request after the transfer.

Possible errors

Status code Error message
400 Amount to transfer is too large
Device is deleted
Device is not active
Insufficient balance to transfer asset
Invalid asset ID
Invalid parameters
Invalid receiving device
Not enough credits to pay for transfer asset service
403 No permission to transfer asset to receiving device
500 Internal server error
503 System currently not available; please try again at a later time

Retrieve Asset Info

Gets information about a given asset.

Sample request:

GET /api/0.6/assets/aQjlzShmrnEZeeYBZihc HTTP/1.1
X-BCoT-Timestamp: 20180417T143840Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=d73532614d4e46fb4e9be59255a660b540a122322aa7800fcb8a0ea4c3a0e40a
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.6/assets/aQjlzShmrnEZeeYBZihc" \
     -H 'X-BCoT-Timestamp: 20180417T143900Z' \
     -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=b6501dab96c6838807817c63d9e75f5020806c5a4a0075558a7ff3477b468a1a'
<script src="CatenisAPIClientJS.min.js"></script>

<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

var assetId = 'aQjlzShmrnEZeeYBZihc';

ctnApiClient.retrieveAssetInfo(assetId,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            console.log('Asset info:', data);
        }
});
</script>
var CtnApiClient = require('catenis-api-client');

var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

var assetId = 'aQjlzShmrnEZeeYBZihc';

ctnApiClient.retrieveAssetInfo(assetId,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            console.log('Asset info:', data);
        }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

$assetId = 'aQjlzShmrnEZeeYBZihc';

try {
    $data = $ctnApiClient->retrieveAssetInfo($assetId);

    // Process returned data
    echo 'Asset info:' . print_r($data, true);
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

// TODO: complete source code

try {
    // TODO: complete source code
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::endl;
}

Request

GET /assets/:assetId

Parameters

Sample response:

{
  "status": "success",
  "data": {
    "assetId": "aQjlzShmrnEZeeYBZihc",
    "name": "XYZ001",
    "description": "Testing asset #1",
    "canReissue": true,
    "decimalPlaces": 2,
    "issuer": {
      "deviceId": "dnN3Ea43bhMTHtTvpytS",
      "name": "deviceB",
      "prodUniqueId": "XYZABC001"
    },
    "totalExistentBalance": 1650
  }
}

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.
  assetId String The ID of the asset.
  name String The name of the asset.
  description String The description of the asset.
  canReissue Boolean Indicates whether more units of this asset can be issued.
  decimalPlaces Number The maximum number of decimal places that can be used to specify a fractional amount of this asset.
  issuer Object The virtual device that originally issued this asset — the issuing device.
    deviceId String The device ID of the issuing device.
    name String (only returned if issuing device has this data, and the virtual device issuing the request has the necessary permission right) The name of the issuing device.
    prodUniqueId String (only returned if issuing device has this data, and the virtual device issuing the request has the necessary permission right) The product unique ID of the issuing device.
  totalExistentBalance Number The current total balance of the asset in existence.

Possible errors

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

Get Asset Balance

Gets the current balance of a given asset held by the device.

Sample request:

GET /api/0.6/assets/aQjlzShmrnEZeeYBZihc/balance HTTP/1.1
X-BCoT-Timestamp: 20180417T165555Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=0531b1ce00b03de1ca707db48fd2474328e21fdb6930b8661a4608e8fe735b84
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.6/assets/aQjlzShmrnEZeeYBZihc/balance" \
     -H 'X-BCoT-Timestamp: 20180417T165613Z' \
     -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=2f85718595bc2633e13b21315babeb00b60327b317e3c56dab3865f2aa29115c'
<script src="CatenisAPIClientJS.min.js"></script>

<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

var assetId = 'aQjlzShmrnEZeeYBZihc';

ctnApiClient.getAssetBalance(assetId,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            console.log('Current asset balance:', data.balance.total);
            console.log('Amount not yet confirmed:', data.balance.unconfirmed);
        }
});
</script>
var CtnApiClient = require('catenis-api-client');

var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

var assetId = 'aQjlzShmrnEZeeYBZihc';

ctnApiClient.getAssetBalance(assetId,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            console.log('Current asset balance:', data.balance.total);
            console.log('Amount not yet confirmed:', data.balance.unconfirmed);
        }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

$assetId = 'aQjlzShmrnEZeeYBZihc';

try {
    $data = $ctnApiClient->getAssetBalance($assetId);

    // Process returned data
    echo 'Current asset balance: ' . $data->balance->total . PHP_EOL;
    echo 'Amount not yet confirmed: ' . $data->balance->unconfirmed . PHP_EOL;
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

// TODO: complete source code

try {
    // TODO: complete source code
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::endl;
}

Request

GET /assets/:assetId/balance

Parameters

Sample response:

{
  "status": "success",
  "data": {
    "total": 1145.75,
    "unconfirmed": 0
  }
}

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.
  total Number The current balance of the asset held by the device that issues the request.
  unconfirmed Number The amount from the balance that is not yet confirmed.

Possible errors

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

List Owned Assets

Retrieves a list of assets that are currently held by the device.

Sample request:

GET /api/0.6/assets/owned?limit=200 HTTP/1.1
X-BCoT-Timestamp: 20180417T193253Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=e1986d68550fe45536e407ec0eba3d0104579106f3486b9aec652ac0f78add43
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.6/assets/owned?limit=200" \
     -H 'X-BCoT-Timestamp: 20180417T193325Z' \
     -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=2c6c8a066e7e983ad059854a3209ae7cfd024f1be504d51b5939fc3780dce8ae'
<script src="CatenisAPIClientJS.min.js"></script>

<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

ctnApiClient.listOwnedAssets(200, 0,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            data.ownedAssets.forEach(function (ownedAsset, idx) {
                console.log('Owned asset #', idx + 1, ':');
                console.log('  - asset ID:', ownedAsset.assetId);
                console.log('  - current asset balance:', ownedAsset.balance.total);
                console.log('  - amount not yet confirmed:', ownedAsset.balance.unconfirmed);
            });

            if (data.hasMore) {
                console.log('Not all owned assets have been returned');
            }
        }
});
</script>
var CtnApiClient = require('catenis-api-client');

var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

ctnApiClient.listOwnedAssets(200, 0,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            data.ownedAssets.forEach(function (ownedAsset, idx) {
                console.log('Owned asset #', idx + 1, ':');
                console.log('  - asset ID:', ownedAsset.assetId);
                console.log('  - current asset balance:', ownedAsset.balance.total);
                console.log('  - amount not yet confirmed:', ownedAsset.balance.unconfirmed);
            });

            if (data.hasMore) {
                console.log('Not all owned assets have been returned');
            }
        }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

try {
    $data = $ctnApiClient->listOwnedAssets(200, 0);

    // Process returned data
    forEach($data->ownedAssets as $idx => $ownedAsset) {
        echo 'Owned asset #' . ($idx + 1) . ':' . PHP_EOL;
        echo '  - asset ID: ' . $ownedAsset->assetId . PHP_EOL;
        echo '  - current asset balance: ' . $ownedAsset->balance->total . PHP_EOL;
        echo '  - amount not yet confirmed: ' . $ownedAsset->balance->unconfirmed . PHP_EOL;
    }

    if ($data->hasMore) {
        echo 'Not all owned assets have been returned' . PHP_EOL;
    }
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

// TODO: complete source code

try {
    // TODO: complete source code
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::endl;
}

Request

GET /assets/owned

Parameters

Sample response:

{
  "status": "success",
  "data": {
    "ownedAssets": [
      {
        "assetId": "aQjlzShmrnEZeeYBZihc",
        "balance": {
          "total": 1145.75,
          "unconfirmed": 0
        }
      },
      {
        "assetId": "asEKmm6pdJomwmajghDy",
        "balance": {
          "total": 300000,
          "unconfirmed": 0
        }
      }
    ],
    "hasMore": 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.
  ownedAssets Array(Object) The list of owned asset entries returned.
    assetId String The ID of the asset.
    balance Object
      total Number The current balance of that asset held by the device that issues the request.
      unconfirmed Number The amount from the balance that is not yet confirmed.
  hasMore Boolean Indicates whether there are more entries that have not been included in the returned list.

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 Issued Assets

Retrieves a list of assets that have been issued by the device.

Sample request:

GET /api/0.6/assets/issued?limit=200 HTTP/1.1
X-BCoT-Timestamp: 20180417T193403Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=ba41de81d939995b7cf76c03a4bc5861bf2176b7622348648c64fbb6f38dbc3a
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.6/assets/issued?limit=200" \
     -H 'X-BCoT-Timestamp: 20180417T193421Z' \
     -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=eb1e37742272ef732dae3d85cd0d75b32731b6d85d20d501d7969d55ca998849'
<script src="CatenisAPIClientJS.min.js"></script>

<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

ctnApiClient.listIssuedAssets(200, 0,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            data.issuedAssets.forEach(function (issuedAsset, idx) {
                console.log('Issued asset #', idx + 1, ':');
                console.log('  - asset ID:', issuedAsset.assetId);
                console.log('  - total existent balance:', issuedAsset.totalExistentBalance);
            });

            if (data.hasMore) {
                console.log('Not all issued assets have been returned');
            }
        }
});
</script>
var CtnApiClient = require('catenis-api-client');

var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

ctnApiClient.listIssuedAssets(200, 0,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            data.issuedAssets.forEach(function (issuedAsset, idx) {
                console.log('Issued asset #', idx + 1, ':');
                console.log('  - asset ID:', issuedAsset.assetId);
                console.log('  - total existent balance:', issuedAsset.totalExistentBalance);
            });

            if (data.hasMore) {
                console.log('Not all issued assets have been returned');
            }
        }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

try {
    $data = $ctnApiClient->listIssuedAssets(200, 0);

    // Process returned data
    forEach($data->issuedAssets as $idx => $issuedAsset) {
        echo 'Issued asset #' . ($idx + 1) . ':' . PHP_EOL;
        echo '  - asset ID: ' . $issuedAsset->assetId . PHP_EOL;
        echo '  - total existent balance: ' . $issuedAsset->totalExistentBalance . PHP_EOL;
    }

    if ($data->hasMore) {
        echo 'Not all issued assets have been returned' . PHP_EOL;
    }
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

// TODO: complete source code

try {
    // TODO: complete source code
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::endl;
}

Request

GET /assets/issued

Parameters

Sample response:

{
  "status": "success",
  "data": {
    "issuedAssets": [
      {
        "assetId": "aQjlzShmrnEZeeYBZihc",
        "totalExistentBalance": 1650
      }
    ],
    "hasMore": 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.
  issuedAssets Array(Object) The list of issued asset entries returned.
    assetId String The ID of the asset.
    totalExistentBalance Number The current total balance of that asset in existence.
  hasMore Boolean Indicates whether there are more entries that have not been included in the returned list.

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

Retrieve Asset Issuance History

Gets a list of asset issuance events for a given asset that took place within a specified time frame.

Sample request:

GET /api/0.6/assets/aQjlzShmrnEZeeYBZihc/issuance?startDate=20170101T000000Z HTTP/1.1
X-BCoT-Timestamp: 20180417T182853Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=57d779fbb24593ba4eff574e0c87961a3c39561cb90d99546d5041cdd7e964a9
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.6/assets/aQjlzShmrnEZeeYBZihc/issuance?startDate=20170101T000000Z" \
     -H 'X-BCoT-Timestamp: 20180417T182836Z' \
     -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=4990e4df2d0d73d01cd251dab65b6f4d2f702b43eb517d88c5ff3038d0bbd1f6'
<script src="CatenisAPIClientJS.min.js"></script>

<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

var assetId = 'aQjlzShmrnEZeeYBZihc';

ctnApiClient.retrieveAssetIssuanceHistory(assetId, '20170101T000000Z', null,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            data.issuanceEvents.forEach(function (issuanceEvent, idx) {
                console.log('Issuance event #', idx + 1, ':');
                console.log('  - issued amount:', issuanceEvent.amount);
                console.log('  - device to which issued amount had been assigned:', issuanceEvent.holdingDevice);
                console.log('  - date of issuance:', issuanceEvent.date);
            });

            if (data.countExceeded) {
                console.log('Warning: not all asset issuance events that took place within the specified time frame have been returned!';
            }
        }
});
</script>
var CtnApiClient = require('catenis-api-client');

var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

var assetId = 'aQjlzShmrnEZeeYBZihc';

ctnApiClient.retrieveAssetIssuanceHistory(assetId, '20170101T000000Z', null,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            data.issuanceEvents.forEach(function (issuanceEvent, idx) {
                console.log('Issuance event #', idx + 1, ':');
                console.log('  - issued amount:', issuanceEvent.amount);
                console.log('  - device to which issued amount had been assigned:', issuanceEvent.holdingDevice);
                console.log('  - date of issuance:', issuanceEvent.date);
            });

            if (data.countExceeded) {
                console.log('Warning: not all asset issuance events that took place within the specified time frame have been returned!';
            }
        }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

$assetId = 'aQjlzShmrnEZeeYBZihc';

try {
    $data = $ctnApiClient->retrieveAssetIssuanceHistory($assetId, '20170101T000000Z');

    // Process returned data
    forEach($data->issuanceEvents as $idx => $issuanceEvent) {
        echo 'Issuance event #', ($idx + 1) . ':' . PHP_EOL;
        echo '  - issued amount: ' . $issuanceEvent->amount . PHP_EOL;
        echo '  - device to which issued amount had been assigned: ' . print_r($issuanceEvent->holdingDevice, true);
        echo '  - date of issuance: ' . $issuanceEvent->date . PHP_EOL;
    }

    if ($data->countExceeded) {
        echo 'Warning: not all asset issuance events that took place within the specified time frame have been returned!' . PHP_EOL;
    }
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

// TODO: complete source code

try {
    // TODO: complete source code
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::endl;
}

Request

GET /assets/:assetId/issuance

Parameters

Sample response:

{
  "status": "success",
  "data": {
    "issuances": [
      {
        "amount": 1200,
        "holdingDevice": {
          "deviceId": "dnN3Ea43bhMTHtTvpytS",
          "name": "deviceB",
          "prodUniqueId": "XYZABC001"
        },
        "date": "2018-03-27T21:43:15.050Z"
      },
      {
        "amount": 450,
        "holdingDevice": {
          "deviceId": "dv3htgvK7hjnKx3617Re",
          "name": "Catenis device #1"
        },
        "date": "2018-03-28T12:20:31.738Z"
      }
    ],
    "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.
  issuances Array(Object) The list of asset issuance events returned. The events are sorted in ascending order in regard to the returned date field.
    amount Number The amount of the asset issued.
    holdingDevice Object The virtual device to which the issued amount was assigned.
      deviceId String The device ID of the holding device.
      name String (only returned if holding device has this data, and the virtual device issuing the request has the necessary permission right) The name of the holding device.
      prodUniqueId String (only returned if holding device has this data, and the virtual device issuing the request has the necessary permission right) The product unique ID of the holding device.
  countExceeded Boolean Indicates whether the number of asset issuance events that satisfies the search criteria exceeded the maximum allowed number of returned asset issuance events, and thus the returned result set had been truncated.

Possible errors

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

List Asset Holders

Retrieves a list of virtual devices that currently hold any amount of a given asset.

Sample request:

GET /api/0.6/assets/aQjlzShmrnEZeeYBZihc/holders?limit=200 HTTP/1.1
X-BCoT-Timestamp: 20180417T193524Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=2a5d3aa86d303ed552b408356ae30174f428fab8c377c1f203812ad0b036cfa4
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.6/assets/aQjlzShmrnEZeeYBZihc/holders?limit=200" \
     -H 'X-BCoT-Timestamp: 20180417T193542Z' \
     -H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=57ba39226a41800f13f7c985aa6f1ccca98ce6817c15680090e9e18a0ade7e0b'
<script src="CatenisAPIClientJS.min.js"></script>

<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

var assetId = 'aQjlzShmrnEZeeYBZihc';

ctnApiClient.listAssetHolders(assetId, 200, 0,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            data.assetHolders.forEach(function (assetHolder, idx) {
                console.log('Asset holder #', idx + 1, ':');
                console.log('  - device holding an amount of the asset:', assetHolder.holder);
                console.log('  - amount of asset currently held by device:', assetHolder.balance.total);
                console.log('  - amount not yet confirmed:', assetHolder.balance.unconfirmed);
            });

            if (data.hasMore) {
                console.log('Not all asset holders have been returned');
            }
        }
});
</script>
var CtnApiClient = require('catenis-api-client');

var deviceId = 'dnN3Ea43bhMTHtTvpytS';

var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
    environment: 'sandbox'
});

var assetId = 'aQjlzShmrnEZeeYBZihc';

ctnApiClient.listAssetHolders(assetId, 200, 0,
    function (err, data) {
        if (err) {
            // Process error
        }
        else {
            // Process returned data
            data.assetHolders.forEach(function (assetHolder, idx) {
                console.log('Asset holder #', idx + 1, ':');
                console.log('  - device holding an amount of the asset:', assetHolder.holder);
                console.log('  - amount of asset currently held by device:', assetHolder.balance.total);
                console.log('  - amount not yet confirmed:', assetHolder.balance.unconfirmed);
            });

            if (data.hasMore) {
                console.log('Not all asset holders have been returned');
            }
        }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

$assetId = 'aQjlzShmrnEZeeYBZihc';

try {
    $data = $ctnApiClient->listAssetHolders($assetId, 200, 0);

    // Process returned data
    forEach($data->assetHolders as $idx => $assetHolder) {
        echo 'Asset holder #' . ($idx + 1) . ':' . PHP_EOL;
        echo '  - device holding an amount of the asset: ' . print_r($assetHolder->holder, true);
        echo '  - amount of asset currently held by device: ' . $assetHolder->balance->total . PHP_EOL;
        echo '  - amount not yet confirmed: ' . $assetHolder->balance->unconfirmed . PHP_EOL;
    }

    if ($data->hasMore) {
        echo 'Not all asset holders have been returned' . PHP_EOL;
    }
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

// TODO: complete source code

try {
    // TODO: complete source code
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::endl;
}

Request

GET /assets/:assetId/holders

Parameters

Sample response:

{
  "status": "success",
  "data": {
    "assetHolders": [
      {
        "holder": {
          "deviceId": "dnN3Ea43bhMTHtTvpytS",
          "name": "deviceB",
          "prodUniqueId": "XYZABC001"
        },
        "balance": {
          "total": 1145.75,
          "unconfirmed": 0
        }
      },
      {
        "holder": {
          "deviceId": "dv3htgvK7hjnKx3617Re",
          "name": "Catenis device #1"
        },
        "balance": {
          "total": 504.25,
          "unconfirmed": 0
        }
      }
    ],
    "hasMore": 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.
  assetHolders Array(Object) The list of asset holder entries returned.
    holder Object The virtual device that holds an amount of the asset — the holding device.
      deviceId String The device ID of the holding device.
      name String (only returned if holding device has this data, and the virtual device issuing the request has the necessary permission right) The name of the holding device.
      prodUniqueId String (only returned if holding device has this data, and the virtual device issuing the request has the necessary permission right) The product unique ID of the holding device.
    balance Object
      total Number The current balance of the asset held by this holding device.
      unconfirmed Number The amount from the balance that is not yet confirmed.
  hasMore Boolean Indicates whether there are more entries that have not been included in the returned list.

Possible errors

Status code Error message
400 Device is deleted
Device is not active
Invalid asset ID
Invalid parameters
403 No permission to list asset holders
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.6/permission/events HTTP/1.1
X-BCoT-Timestamp: 20180217T165054Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180217/ctn1_request, Signature=138e50e836dec8c78d48a46bd04c03434ff994b2cf59d929dff324e958f2c096
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.6/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: 'sandbox'
});

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: 'sandbox'
});

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]);
        });
    }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

try {
    $data = $ctnApiClient->listPermissionEvents();

    // Process returned data
    forEach($data as $eventName => $description) {
        echo 'Event name: ' . $eventName . '; event description: ' . $description . PHP_EOL;
    }
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

ctn::ListPermissionEventsResult data;

try {
    ctnApiClient.listPermissionEvents(data);

    for (auto it = data.permissionEvents.begin(); it != data.permissionEvents.end(); it++) {
        std::cout << "Event name: " << it->first << "; event description: " << it->second << std::endl;
    }
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::endl;
}

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.6/permission/events/receive-msg/rights HTTP/1.1
X-BCoT-Timestamp: 20180217T193337Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180217/ctn1_request, Signature=b6bf27017c8ee92da349f80e27e127f3c2cb3adeeeee28e19c18d9b9c3b752a8
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.6/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: 'sandbox'
});

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: 'sandbox'
});

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);
            }
        }
    }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

try {
    $data = $ctnApiClient->retrievePermissionRights('receive-msg');

    // Process returned data
    echo 'Default (system) permission right: ' . $data->system . PHP_EOL;

    if (isset($data->catenisNode)) {
        if (isset($data->catenisNode->allow)) {
            echo 'Index of Catenis nodes with \'allow\' permission right: ' . implode($data->catenisNode->allow, ', ') . PHP_EOL;
        }

        if (isset($data->catenisNode->deny)) {
            echo 'Index of Catenis nodes with \'deny\' permission right: ' . implode($data->catenisNode->deny, ', ') . PHP_EOL;
        }
    }

    if (isset($data->client)) {
        if (isset($data->client->allow)) {
            echo 'ID of clients with \'allow\' permission right: ' . implode($data->client->allow, ', ') . PHP_EOL;
        }

        if (isset($data->client->deny)) {
            echo 'ID of clients with \'deny\' permission right: ' . implode($data->client->deny, ', ') . PHP_EOL;
        }
    }

    if (isset($data->device)) {
        if (isset($data->device->allow)) {
            echo 'Devices with \'allow\' permission right: ' . print_r($data->device->allow, true);
        }

        if (isset($data->device->deny)) {
            echo 'Devices with \'deny\' permission right: ' . print_r($data->device->deny, true);
        }
    }
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

ctn::RetrievePermissionRightsResult data;

try {
    ctnApiClient.retrievePermissionRights(data, "receive-msg");

    std::cout << "Default (system) permission right: " << data.system << std::endl;

    if (data.catenisNode != nullptr) {
        if (data.catenisNode->allowed.size() > 0) {
            // Process Catenis nodes with 'allow' permission right
        }

        if (data.catenisNode->denied.size() > 0) {
            // Process Catenis nodes with 'deny' permission right
        }
    }

    if (data.client != nullptr) {
        if (data.client->allowed.size() > 0) {
            // Process clients with 'allow' permission right
        }

        if (data.client->denied.size() > 0) {
            // Process clients with 'deny' permission right
        }
    }

    if (data.device != nullptr) {
        if (data.device->allowed.size() > 0) {
            // Process devices with 'allow' permission right
        }

        if (data.device->denied.size() > 0) {
            // Process devices with 'deny' permission right
        }
    }
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::endl;
}

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.6/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: sandbox.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://sandbox.catenis.io/api/0.6/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: 'sandbox'
});

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: 'sandbox'
});

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');
        }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

try {
    $data = $ctnApiClient->setPermissionRights('receive-msg', [
        'client' => [
            'allow' => 'self',
            'deny' => 'cjNhuvGMUYoepFcRZadP'
        ],
        'device' => [
            'allow' => [[
                'id' => 'dv3htgvK7hjnKx3617Re'
            ], [
                'id' => 'XYZ0001',
                'isProdUniqueId' => true
            ]]
        ]
    ]);

    // Process returned data
    echo 'Permission rights successfully set' . PHP_EOL;
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

ctn::SetRightsClient clientRights;
clientRights.allowed.push_back(std::string("self"));
clientRights.denied.push_back(std::string("cjNhuvGMUYoepFcRZadP"));

ctn::SetRightsDevice deviceRights;
deviceRights.allowed.push_back(ctn::Device("dv3htgvK7hjnKx3617Re"));
deviceRights.allowed.push_back(ctn::Device("XYZ0001", true));

try {
    ctnApiClient.setPermissionRights(data, "receive-msg", "", nullptr, &clientRights, &deviceRights);

    std::cout << "Permission rights successfully set" << std::endl;
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::endl;
}

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.6/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: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.6/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: 'sandbox'
});

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: 'sandbox'
});

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]);
    }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

$checkDeviceId = 'dv3htgvK7hjnKx3617Re';

try {
    $data = $ctnApiClient->checkEffectivePermissionRight('receive-msg', $checkDeviceId);

    // Process returned data
    $deviceId = array_keys(get_object_vars($data))[0];
    echo 'Effective right for device ' . $deviceId . ': ' . $data->$deviceId . PHP_EOL;
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

ctn::CheckEffectivePermissionRightResult data;
ctn::Device checkDevice("dv3htgvK7hjnKx3617Re");

try {
    ctnApiClient.checkEffectivePermissionRight(data, "receive-msg", checkDevice);

    std::cout << "Effective right for device " << data.effectivePermissionRight.begin()->first << ": " << data.effectivePermissionRight.begin()->second << std::endl;
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::endl;
}

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.6/devices/dv3htgvK7hjnKx3617Re HTTP/1.1
X-BCoT-Timestamp: 20180219T133757Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180219/ctn1_request, Signature=ff2a8f3d8dc232d60208dc28f668351234ed25ead274e820ac081a480a275012
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.6/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: 'sandbox'
});

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: 'sandbox'
});

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);
    }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

$checkDeviceId = 'dv3htgvK7hjnKx3617Re';

try {
    $data = $ctnApiClient->retrieveDeviceIdentificationInfo($checkDeviceId);

    // Process returned data
    echo 'Device\'s Catenis node ID info:' . print_r($data->catenisNode, true);
    echo 'Device\'s client ID info:' . print_r($data->client, true);
    echo 'Device\'s own ID info:' . print_r($data->device, true);
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

ctn::DeviceIdInfoResult data;

try {
    ctnApiClient.retrieveDeviceIdInfo(data, ctn::Device(deviceId));

    std::cout << "Device\'s Catenis node info:" << std::endl;
    std::cout << "  index: " << data.catenisNode->index << std::endl;

    // Process further returned Catenis node info

    std::cout << "Device\'s client info:" << std::endl;
    std::cout << "  clientId: " << data.client->clientId << std::endl;

    // Process further returned client info

    std::cout << "Device\'s own info:" << std::endl;
    std::cout << "  deviceId: " << data.device->deviceId << std::endl;

    // Process further returned device info
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::endl;
}

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.6/notification/events HTTP/1.1
X-BCoT-Timestamp: 20180219T160411Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180219/ctn1_request, Signature=02e8f56a46e2ea8001f94fac04115749606deacd5eee6f553b6d69c5d45ce553
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.6/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: 'sandbox'
});

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: 'sandbox'
});

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]);
        });
    }
});
<?php
require __DIR__ . '/vendor/autoload.php';

use Catenis\ApiClient;
use Catenis\Exception\CatenisException;

$deviceId = 'dnN3Ea43bhMTHtTvpytS';

$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
    'environment' => 'sandbox'
]);

try {
    $data = $ctnApiClient->listNotificationEvents();

    // Process returned data
    forEach($data as $eventName => $description) {
        echo 'Event name: ' . $eventName . '; event description: ' . $description . PHP_EOL;
    }
}
catch (CatenisException $ex) {
    // Process exception
}
#include "CatenisApiClient.h"

std::string device_id("dnN3Ea43bhMTHtTvpytS");

ctn::CtnApiClient ctnApiClient(device_id, api_access_secret, "catenis.io", "", "sandbox");

ctn::ListNotificationEventsResult data;

try {
    ctnApiClient.listNotificationEvents(data);

    for (auto it = data.notificationEvents.begin(); it != data.notificationEvents.end(); it++) {
        std::cout << "Event name: " << it->first << "; event description: " << it->second << std::endl;
    }
}
catch (ctn::CatenisAPIException &errObject) {
    std::cerr << errObject.getErrorDescription() << std::endl;
}

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 service 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.

The Catenis notification service is currently at version 0.1.

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)
asset-received An amount of an asset has been received
asset-confirmed An amount of an asset that was pending due to an asset transfer has been confirmed

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 virtual 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.

Asset amount received (asset-received)

Sample notification message:

{
  "assetId": "aQjlzShmrnEZeeYBZihc",
  "issuer": {
    "deviceId": "dnN3Ea43bhMTHtTvpytS",
    "name": "deviceB",
    "prodUniqueId": "XYZABC001"
  },
  "from": {
    "deviceId": "dv3htgvK7hjnKx3617Re",
    "name": "Catenis device #1"
  },
  "receivedDate": "2018-04-01T17:15:36.134Z"
}

A JSON containing the following properties:

Property Type Description
assetId String The ID of the received asset.
amount Amount The amount of the asset that has been received.
issuer Object Identifies the virtual device that issued the asset — the issuing device.
  deviceId String The device ID of the issuing device.
  name String (only returned if issuing device has this data, and the device receiving the notification has the necessary permission right) The name of the issuing device.
  prodUniqueId String (only returned if issuing device has this data, and the device receiving the notification has the necessary permission right) The product unique ID of the issuing device.
from Object Identifies the virtual device that sent or assigned the asset amount — the sending device.
  deviceId String The device ID of the sending device.
  name String (only returned if sending device has this data, and the device receiving the notification has the necessary permission right) The name of the sending device.
  prodUniqueId String (only returned if sending device has this data, and the device receiving the notification has the necessary permission right) The product unique ID of the sending device.
receivedDate String ISO 8601 formatted date and time when the asset amount has been received.

Asset amount confirmed (asset-confirmed)

Sample notification message:

{
  "assetId": "aQjlzShmrnEZeeYBZihc",
  "amount": 54.25,
  "issuer": {
    "deviceId": "dnN3Ea43bhMTHtTvpytS",
    "name": "deviceB",
    "prodUniqueId": "XYZABC001"
  },
  "from": {
    "deviceId": "dv3htgvK7hjnKx3617Re",
    "name": "Catenis device #1"
  },
  "confirmedDate": "2018-04-01T17:32:03.012Z"
}

A JSON containing the following properties:

Property Type Description
assetId String The ID of the confirmed asset.
amount Amount The amount of the asset that has been confirmed.
issuer Object Identifies the virtual device that issued the asset — the issuing device.
  deviceId String The device ID of the issuing device.
  name String (only returned if issuing device has this data, and the device receiving the notification has the necessary permission right) The name of the issuing device.
  prodUniqueId String (only returned if issuing device has this data, and the device receiving the notification has the necessary permission right) The product unique ID of the issuing device.
from Object Identifies the virtual device that originally sent or assigned the asset amount — the sending device.
  deviceId String The device ID of the sending device.
  name String (only returned if sending device has this data, and the device receiving the notification has the necessary permission right) The name of the sending device.
  prodUniqueId String (only returned if sending device has this data, and the device receiving the notification has the necessary permission right) The product unique ID of the sending device.
confirmedDate String ISO 8601 formatted date and time when the asset amount has been confirmed.

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 message dispatcher used.

The following notification message dispatchers are currently available:

WebSocket notification message dispatcher

This notification message dispatcher uses a WebSocket connection as the communication transport for the notification channel.

The WebSocket notification message dispatcher is currently at version 0.1.

To open a notification channel, one needs to establish a WebSocket connection using the information provided below.

Connection endpoint URL

Sandbox environment: wss://sandbox.catenis.io/api/notify/0.1/ws/0.1/:eventName

Parameters

WebSocket subprotocol

notify.catenis.io

Authentication

The following steps should be taken in order to successfully authenticate the virtual device when establishing a WebSocket connection to open the 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: sandbox.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
Amount to issue is too large The specified amount of asset to be issued is larger than the largest allowed amount (2^53 - 1), or the total available amount of the asset, after the issuance, would be larger than the largest allowed amount.
Amount to transfer is too large The specified amount of asset to be transferred is larger than the largest allowed amount (2^53 - 1).
Asset cannot be reissued The specified asset does not allow for more units of it to be issued after its first issuance.
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.
Insufficient balance to transfer asset Virtual device does not currently hold enough units of the asset to fulfill the transfer.
Internal server error An unexpected situation prevented Catenis Enterprise from correctly processing the request.
Invalid asset ID The supplied asset ID is invalid or no asset with that ID could be found.
Invalid device The ID (either the device ID or the product unique ID) for the virtual device to hold the issued assets is not valid or there is no virtual device with that ID.
Invalid holding device The ID (either the device ID or the product unique ID) for the virtual device to hold the issued asset amount 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 receiving device The ID (either the device ID or the product unique ID) for the virtual device to receive the transferred assets is not valid or there is no virtual device with that ID.
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.
Not enough credits to pay for issue asset service The client service account balance is too low to cover the issue asset service's expense.
Not enough credits to pay for log message service The client service account balance is too low to cover the log message service's expense.
Not enough credits to pay for send message service The client service account balance is too low to cover the send message service's expense.
Not enough credits to pay for transfer asset service The client service account balance is too low to cover the transfer asset service's expense.
No permission to assign issued asset to holding device Virtual device has no permission to assign the amount of the asset to be issued to the specified holding device.
No permission to list asset holders Virtual device has no permission to list holders of the requested asset.
No permission to read message Virtual device has no permission to read the requested message.
No permission to reissue asset Virtual device attempting to issue more units of the asset is not the device that issued the initial amount of that asset.
No permission to retrieve asset info Virtual device has no permission to retrieve information about the requested asset.
No permission to retrieve asset issuance history Virtual device has no permission to retrieve issuance history of the requested asset.
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 that sent/logged the message.
No permission to transfer asset to receiving device Virtual device has no permission to transfer an amount of the asset to the specified receiving device.
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.