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.9 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.9/
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:
System - it is the default permission right.
Catenis node - it controls the permission right for all devices that belong to any client defined for that Catenis node.
Client - it controls the permission right for all devices that belong to this client.
Device - it controls the permission right for this specific device.
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:
Starting at the device level, we check if the permission right for that (controlled) device is set. If it is set, this is the permission right that is in effect.
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 it is set, this is the permission right that is in effect.
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 it is set, this is the permission right that is in effect.
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:
- Constructs an HTTP request for the API method that needs to be called;
- Signs the request using the virtual device's API access secret;
- 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.9/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.9/message/send\nhost:api.catenis.com\nx-bcot-timestamp:20180127T121358Z\n\n792cdbeef04dc33e8ebb4974070ec5a75bd1e3a6c5ef49b1c3ec1b87152694c6\n"
Printed text:
POST
api/0.9/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.9/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.9/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. |
Authentication related errors
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.9.
Log Message
Records a message on the blockchain.
Sample request:
POST /api/0.9/messages/log HTTP/1.1
X-BCoT-Timestamp: 20200122T195904Z
Authorization: CTN1-HMAC-SHA256 Credential=d8YpQ7jgPBJEkBrnvp58/20200122/ctn1_request, Signature=867604b6d15575907e6c40ca8ef5f5d07c4791eed1a7a6a0fc358cd5d850948a
Content-Type: application/json; charset=utf-8
Host: localhost:3000
Connection: close
User-Agent: Paw/3.1.10 (Macintosh; OS X/10.15.2) GCDHTTPRequest
Content-Length: 111
{"message":"This is only a test","options":{"encoding":"utf8","encrypt":true,"offChain":true,"storage":"auto"}}
curl -X "POST" "http://localhost:3000/api/0.9/messages/log" \
-H 'X-BCoT-Timestamp: 20200122T195936Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=d8YpQ7jgPBJEkBrnvp58/20200122/ctn1_request, Signature=a68ef08c0f45b23a557440cc505380b30c1850828c75b8a96d351d129d3022db' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"message": "This is only a test",
"options": {
"encoding": "utf8",
"encrypt": true,
"offChain": 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,
offChain: 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,
offChain: 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,
'offChain' => true,
'storage' => 'auto'
]);
// Process returned data
echo 'ID of logged message: ' . $data->messageId . PHP_EOL;
}
catch (CatenisException $ex) {
// Process exception
}
Request
POST /messages/log
Parameters
- Request body:
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
message |
String|Object | The message to record. If an object is passed instead, it is expected that the message be passed in chunks. |
data |
String | (optional) The next message data chunk. The actual message's contents should be comprised of one or more data chunks. |
isFinal |
Boolean | (optional, default: true ) Indicates whether this is the final message data chunk. |
continuationToken |
String | (optional) Indicates that this is a continuation message data chunk. It should be filled with the value returned in the continuationToken field of the response to the request used to pass the previous message data chunk. |
options |
Object | (optional) |
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. |
offChain |
Boolean | (optional, default: true ) Indicates whether message should be logged as a Catenis off-chain message. |
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. |
async |
Boolean | (optional, default: false ) Indicates whether processing — storage of message to the blockchain — should be done asynchronously. |
Sample response:
{
"status": "success",
"data": {
"messageId": "ouczbRbcgo3F8XoC6ejE"
}
}
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. |
continuationToken |
String | (only returned if passing message in chunks and last message data chunk was not final) Token to be used when sending the following message data chunk. |
messageId |
String | (only returned after message has been processed) ID of the logged message. |
provisionalMessageId |
String | (only returned if doing asynchronous processing after the whole message's contents are passed) ID of provisional message. |
Possible errors
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.9/messages/send HTTP/1.1
X-BCoT-Timestamp: 20200122T200146Z
Authorization: CTN1-HMAC-SHA256 Credential=d8YpQ7jgPBJEkBrnvp58/20200122/ctn1_request, Signature=bb952d55523490deb8dafd2c0f7d7acaf71959026fa844a2fa36de1084d3d54c
Content-Type: application/json; charset=utf-8
Host: localhost:3000
Connection: close
User-Agent: Paw/3.1.10 (Macintosh; OS X/10.15.2) GCDHTTPRequest
Content-Length: 180
{"message":"This is only a test","targetDevice":{"id":"dv3htgvK7hjnKx3617Re"},"options":{"encoding":"utf8","encrypt":true,"offChain":true,"storage":"auto","readConfirmation":true}}
curl -X "POST" "http://localhost:3000/api/0.9/messages/send" \
-H 'X-BCoT-Timestamp: 20200122T200220Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=d8YpQ7jgPBJEkBrnvp58/20200122/ctn1_request, Signature=406727fab045ade27eb6fa87012698b542aca4a44b889951dee249b05350b3b9' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"message": "This is only a test",
"options": {
"encoding": "utf8",
"encrypt": true,
"offChain": true,
"storage": "auto",
"readConfirmation": true
},
"targetDevice": {
"id": "dv3htgvK7hjnKx3617Re"
}
}'
<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('This is only a test', targetDevice, {
encoding: 'utf8',
encrypt: true,
offChain: true,
storage: 'auto',
readConfirmation: true
},
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', {
encoding: 'utf8',
encrypt: true,
offChain: true,
storage: 'auto',
readConfirmation: true
},
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', [
'encoding' => 'utf8',
'encrypt' => true,
'offChain' => true,
'storage' => 'auto',
'readConfirmation' => true
]);
// Process returned data
echo 'ID of sent message: ' . $data->messageId . PHP_EOL;
}
catch (CatenisException $ex) {
// Process exception
}
Request
POST /messages/send
Parameters
- Request body:
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
message |
String|Object | The message to send. If an object is passed instead, it is expected that the message be passed in chunks. |
data |
String | (optional) The next message data chunk. The actual message's contents should be comprised of one or more data chunks. |
isFinal |
Boolean | (optional, default: true ) Indicates whether this is the final message data chunk. |
continuationToken |
String | (optional) Indicates that this is a continuation message data chunk. It should be filled with the value returned in the continuationToken field of the response to the request used to pass the previous message data chunk. |
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. |
options |
Object | (optional) |
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. |
offChain |
Boolean | (optional, default: true ) Indicates whether message should be sent as a Catenis off-chain message. |
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. |
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. |
async |
Boolean | (optional, default: false ) Indicates whether processing — storage of message to the blockchain — should be done asynchronously. |
Sample response:
{
"status": "success",
"data": {
"messageId": "ouczbRbcgo3F8XoC6ejE"
}
}
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. |
continuationToken |
String | (only returned if passing message in chunks and last message data chunk was not final) Token to be used when sending the following message data chunk. |
messageId |
String | (only returned after message has been processed) ID of the sent message. |
provisionalMessageId |
String | (only returned if doing asynchronous processing after the whole message's contents are passed) ID of provisional message. |
Possible errors
Read Message
Retrieves the contents of a message that had been previously recorded on the blockchain.
Sample request:
GET /api/0.9/messages/oDWPuD5kjCsEiNEEWwrW?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.9/messages/oDWPuD5kjCsEiNEEWwrW?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 = 'oDWPuD5kjCsEiNEEWwrW';
ctnApiClient.readMessage(messageId, 'utf8', function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Read message:', data.msgData.message);
if (data.msgInfo.action === 'send') {
console.log('Message sent from:', data.msgInfo.from);
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var messageId = 'oDWPuD5kjCsEiNEEWwrW';
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 = 'oDWPuD5kjCsEiNEEWwrW';
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
}
Request
GET /messages/:messageId
Parameters
URL parameters:
messageId
: The ID of the message to read.
Query string parameters:
encoding
: (optional, default:utf8
) The encoding to be used for the contents of the message. Valid values:utf8
,base64
,hex
.continuationToken
: (optional) Indicates that this is a continuation call and that the following message data chunk should be returned. It should be filled with the value returned in thecontinuationToken
field of the response to the request used to retrieve the previous message data chunk, or the request to the Retrieve Message Progress API method.dataChunkSize
: (optional) Size, in bytes, of the largest message data chunk that should be returned. This is effectively used to signal that the message should be read in chunks. It must be an integer value between 1,024 (1 KB) and 15,728,640 (15 MB).async
: (optional, default:false
) A boolean value indicating whether processing — retrieval of message from the blockchain — should be done asynchronously.
Sample response:
{
"status": "success",
"data": {
"msgInfo": {
"action": "send",
"from": {
"deviceId": "dv3htgvK7hjnKx3617Re",
"name": "Catenis device #1"
}
},
"msgData": "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. |
msgInfo |
Object | (only returned along with the msgData field if not reading the message in chunks or for the first message data chunk returned) Info about the read 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. |
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. |
msgData |
String | (always returned except when cachedMessageId field is returned) The contents of the message formatted using the specified encoding. When reading the message in chunks, this corresponds to a message data chunk. In that case, additional calls to this API method might be necessary to read the whole message's contents. |
continuationToken |
String | (only returned along with the msgData field if the whole message's contents have not yet been returned) Token to be used when requesting the following message data chunk. |
cachedMessageId |
String | (only returned as a response to the initial call to this API method to read a given message asynchronously — async parameter set to true ) Cached message ID. |
Possible errors
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.9/messages/oDWPuD5kjCsEiNEEWwrW/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.9/messages/oDWPuD5kjCsEiNEEWwrW/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 = 'oDWPuD5kjCsEiNEEWwrW';
ctnApiClient.retrieveMessageContainer(messageId, function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
if (data.offChain) {
console.log('IPFS CID of Catenis off-chain message envelope:', data.offChain.cid);
}
if (data.blockchain) {
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 = 'oDWPuD5kjCsEiNEEWwrW';
ctnApiClient.retrieveMessageContainer(messageId, function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
if (data.offChain) {
console.log('IPFS CID of Catenis off-chain message envelope:', data.offChain.cid);
}
if (data.blockchain) {
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 = 'oDWPuD5kjCsEiNEEWwrW';
try {
$data = $ctnApiClient->retrieveMessageContainer($messageId);
// Process returned data
if (isset($data->offChain)) {
echo 'IPFS CID of Catenis off-chain message envelope: ' . $data->offChain->cid . PHP_EOL;
}
if (isset($data->blockchain)) {
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 . PHP_EOL;
}
}
catch (CatenisException $ex) {
// Process exception
}
Request
GET /messages/:messageId
/container
Parameters
- URL parameters:
messageId
: The ID of the message the container of which is to be retrieved.
Sample response:
{
"status": "success",
"data": {
"offChain": {
"cid": "QmUPNgbkB2esFHLZdS5rhD8wxFaCBU8JeBrBePWqMfSWub"
},
"blockchain": {
"txid": "e4080d2badac0b4d4524aa20cd3abfa2f1bdd05a15c85b9d156374c7c6bbfc82",
"isConfirmed": true
},
"externalStorage": {
"ipfs": "QmQ2UaYLHwSjU4VvHyD4SfCUyo7AvrufdNrX1kmsbtbn3w"
}
}
}
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. |
offChain |
Object | (only returned for Catenis off-chain messages) |
cid |
String | IPFS CID of Catenis off-chain message envelope data structure that holds the off-chain message's contents. |
blockchain |
Object | (for Catenis off-chain messages, this property refers to the transaction used to settle the message to the blockchain, and it is only returned at a later time after the settlement takes place) |
txid |
String | The ID of the blockchain transaction where the message was recorded. |
isConfirmed |
Boolean | Indicates whether the blockchain transaction has already been confirmed. |
externalStorage |
Object | (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 | 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 |
Retrieve Message Progress
Retrieves the current status of the asynchronous processing of a message.
Sample request:
GET /api/0.9/messages/hfHtyPCS68toB9FjA8rM/progress HTTP/1.1
X-BCoT-Timestamp: 20190318T212628Z
Authorization: CTN1-HMAC-SHA256 Credential=dL8zaQDcyNvxRW3FqsJd/20190318/ctn1_request, Signature=d98b79672098eeea5f261e102d213168f757c3234a3ee28a2192b5acd739e664
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.8 (Macintosh; OS X/10.14.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.9/messages/hfHtyPCS68toB9FjA8rM/progress" \
-H 'X-BCoT-Timestamp: 20190318T212739Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dL8zaQDcyNvxRW3FqsJd/20190318/ctn1_request, Signature=3ee6e3c7fe58319e4b53a7342a38af2a923908bbe1da5864f5f800d7330abdc1'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var cachedMessageId = 'hfHtyPCS68toB9FjA8rM';
ctnApiClient.retrieveMessageProgress(cachedMessageId,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Number of bytes processed so far:', data.progress.bytesProcessed);
if (data.progress.done) {
if (data.progress.success) {
// Get result
console.log('Asynchronous processing result:', data.result);
}
else {
// Process error
console.error('Asynchronous processing error: [', data.progress.error.code, ' ] -', data.progress.error.message);
}
}
else {
// Asynchronous processing not done yet. Continue pooling
}
}
});</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var cachedMessageId = 'hfHtyPCS68toB9FjA8rM';
ctnApiClient.retrieveMessageProgress(cachedMessageId,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Number of bytes processed so far:', data.progress.bytesProcessed);
if (data.progress.done) {
if (data.progress.success) {
// Get result
console.log('Asynchronous processing result:', data.result);
}
else {
// Process error
console.error('Asynchronous processing error: [', data.progress.error.code, ' ] -', data.progress.error.message);
}
}
else {
// Asynchronous processing not done yet. Continue pooling
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$cachedMessageId = 'hfHtyPCS68toB9FjA8rM';
try {
$data = $ctnApiClient->retrieveMessageProgress($cachedMessageId);
// Process returned data
echo 'Number of bytes processed so far: ' . $data->progress->bytesProcessed . PHP_EOL;
if ($data->progress->done) {
if ($data->progress->success) {
// Get result
echo 'Asynchronous processing result: ' . $data->result . PHP_EOL;
}
else {
// Process error
echo 'Asynchronous processing error: [' . $data->progress->error->code . '] - '
. $data->progress->error->message . PHP_EOL;
}
} else {
// Asynchronous processing not done yet. Continue pooling
}
} catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
Request
GET /messages/:messageId
/progress
Parameters
- URL parameters:
ephemeralMessageId
: ID of ephemeral message — either a provisional or a cached message — for which to return processing progress.
Sample response:
{
"status": "success",
"data": {
"action": "read",
"progress": {
"bytesProcessed": 28,
"done": true,
"success": true,
"finishDate": "2019-03-13T14:09:10.121Z"
},
"result": {
"messageId": "mt7ZYbBYpM3zcgAf3H8X",
"continuationToken": "kjXP2CZaSdkTKCi2jDi2"
}
}
}
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 | The action that was to be performed on the message. One of: log , send , or read . |
progress |
Object | Current processing status. |
bytesProcessed |
Number | Total number of bytes of message that had already been processed. |
done |
Boolean | Indicates whether processing has been finished. |
success |
Boolean | (only returned if processing has already been finished) Indicates whether message has been successfully processed. |
error |
Object | (only returned if processing finished with error) Error information. |
code |
Number | Numeric code — equivalent to an HTML status code — of the error that took place while processing the message. |
message |
String | Text describing the error that took place while processing the message. |
finishDate |
String | (only returned if processing has already been finished) ISO 8601 formatted date and time when processing was finalized. |
result |
Object | (only returned if processing finished successfully) Result of processing. |
messageId |
String | ID of the Catenis message. When logging or sending — action equals to log or send —, it is the ID of the resulting message. When reading — action equals to read —, it references the message being read. |
continuationToken |
String | (only returned if reading message — action equals to read ) The token that should be used to complete the read of the message. |
Possible errors
Status code | Error message |
---|---|
400 | Invalid or expired ephemeral message Progress not available |
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.9/messages?action=send&direction=inbound&fromDeviceIds=dv3htgvK7hjnKx3617Re&readState=unread&startDate=2018-01-01T00:00:00Z&endDate=2018-02-28T23:59:59Z&limit=200&skip=0 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.9/messages?action=send&direction=inbound&fromDeviceIds=dv3htgvK7hjnKx3617Re&readState=unread&startDate=2018-01-01T00:00:00Z&endDate=2018-02-28T23:59:59Z&limit=200&skip=0" \
-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'
}, 200, 0,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
if (data.msgCount > 0) {
console.log('Returned messages:', data.messages);
if (data.hasMore) {
console.log('Not all messages 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'
}, 200, 0,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
if (data.msgCount > 0) {
console.log('Returned messages:', data.messages);
if (data.hasMore) {
console.log('Not all messages 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'
], 200, 0);
// Process returned data
if ($data->msgCount > 0) {
echo 'Returned messages: ' . print_r($data->messages, true);
if ($data->hasMore) {
echo 'Not all messages have been returned' . PHP_EOL;
}
}
}
catch (CatenisException $ex) {
// Process exception
}
Request
GET /messages
Parameters
- Query string parameters:
action
: (optional, default:any
) Action originally performed on the messages to be retrieved. Valid options:log
,send
,any
. Uselog
to retrieve only logged messages, andsend
to retrieve only sent messages. The valueany
can be used to retrieve both logged and sent messages.direction
: (optional, default:any
) The direction of the sent messages to be retrieved. Valid options:inbound
,outbound
,any
. Useinbound
to retrieve only sent messages that had been received by the virtual device issuing the request, andoutbound
to retrieve only sent messages that had been sent by the device issuing the request. The valueany
can be used to retrieve both inbound and outbound messages.fromDeviceIds
: (optional) A comma-separated list of virtual device IDs specifying the devices from which the sent messages to be retrieved had been sent. Note that this option only applies to inbound sent messages.fromDeviceProdUniqueIds
: (optional) A comma-separated list of product unique IDs specifying the devices from which the sent messages to be retrieved had been sent. Note that this option only applies to inbound sent messages.toDeviceIds
: (optional) A comma-separated list of virtual device IDs specifying the devices to which the sent messages to be retrieved had been sent. Note that this option only applies to outbound sent messages.toDeviceProdUniqueIds
: (optional) A comma-separated list of product unique IDs specifying the devices to which the sent messages to be retrieved had been sent. Note that this option only applies to outbound sent messages.readState
: (optional, default:any
) The current read state of the message. Valid options:read
,unread
,any
. Useread
to retrieve only logged or inbound sent messages that had already been read by the virtual device issuing the request, or outbound sent messages sent with the read confirmation option set for which a message read notification has already been received. Useunread
to retrieve only logged or inbound sent messages that had not yet been read by the device issuing the request, or outbound sent messages sent with the read confirmation option set for which a message read notification has not been received yet. Useany
if you do not care about the read state of the message to be retrieved.startDate
: (optional) ISO 8601 formatted date and time specifying the inclusive lower bound of the time frame within which the messages to be retrieved had been: logged, for logged messages; sent, for outbound sent messages; and received, for inbound sent messages.endDate
: (optional) ISO 8601 formatted date and time specifying the inclusive upper bound of the time frame within which the messages to be retrieved had been: logged, for logged messages; sent, for outbound sent messages; and received, for inbound sent messages.limit
: (optional, default:500
) Maximum number of messages that should be returned. Must be a positive integer value not greater than 500.skip
: (optional, default:0
) Number of messages that should be skipped (from beginning of list of matching messages) and not returned. Must be a non-negative (includes zero) integer value.
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,
"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. |
messages |
Array(Object) | The returned list of message information entries including the messages that satisfy 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. |
hasMore |
Boolean | Indicates whether there are more messages that satisfy the search criteria yet to be returned. |
Possible errors
Status code | Error message |
---|---|
400 | 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.9/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.9/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
}
Request
POST /assets/issue
Parameters
- Request body:
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. Must be an integer value between 0 and 7. |
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 newly issued asset. |
Possible errors
Reissue Asset
Issues an additional amount of an existing asset.
Sample request:
POST /api/0.9/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.9/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
}
Request
POST /assets/:assetId
/issue
Parameters
URL parameters:
assetId
: The ID of the asset to issue more units of it.
Request body:
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
Transfer Asset
Transfers an amount of an asset to a device.
Sample request:
POST /api/0.9/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.9/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
}
Request
POST /assets/:assetId
/transfer
Parameters
URL parameters:
assetId
: The ID of the asset to transfer an amount of it.
Request body:
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
Retrieve Asset Info
Gets information about a given asset.
Sample request:
GET /api/0.9/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.9/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
}
Request
GET /assets/:assetId
Parameters
- URL parameters:
assetId
: The ID of the asset to retrieve information.
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 | 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.9/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.9/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
}
Request
GET /assets/:assetId
/balance
Parameters
- URL parameters:
assetId
: The ID of the asset to get balance.
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 | 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.9/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.9/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
}
Request
GET /assets/owned
Parameters
- Query string parameters:
limit
: (optional, default:500
) Maximum number of list items that should be returned. Must be a positive integer value not greater than 500.skip
: (optional, default:0
) Number of list items that should be skipped (from beginning of list) and not returned. Must be a non-negative (includes zero) integer value.
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 | 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.9/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.9/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
}
Request
GET /assets/issued
Parameters
- Query string parameters:
limit
: (optional, default:500
) Maximum number of list items that should be returned. Must be a positive integer value not greater than 500.skip
: (optional, default:0
) Number of list items that should be skipped (from beginning of list) and not returned. Must be a non-negative (includes zero) integer value.
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 | 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.9/assets/aQjlzShmrnEZeeYBZihc/issuance?startDate=20170101T000000Z&limit=200&skip=0 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.9/assets/aQjlzShmrnEZeeYBZihc/issuance?startDate=20170101T000000Z&limit=200&skip=0" \
-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, 200, 0,
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.hasMore) {
console.log('Not all asset issuance events 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, 200, 0,
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.hasMore) {
console.log('Not all asset issuance events 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', null, 200, 0);
// 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->hasMore) {
echo 'Not all asset issuance events have been returned' . PHP_EOL;
}
}
catch (CatenisException $ex) {
// Process exception
}
Request
GET /assets/:assetId
/issuance
Parameters
- URL parameters:
assetId
: The ID of the asset to retrieve the issuance history.
- Query string parameters:
startDate
: (optional) ISO 8601 formatted date and time specifying the inclusive lower bound of the time frame within which amounts of the asset have been issued.endDate
: (optional) ISO 8601 formatted date and time specifying the inclusive upper bound of the time frame within which amounts of the asset have been issued.limit
: (optional, default:500
) Maximum number of asset issuance events that should be returned. Must be a positive integer value not greater than 500.skip
: (optional, default:0
) Number of asset issuance events that should be skipped (from beginning of list of matching events) and not returned. Must be a non-negative (includes zero) integer value.
Sample response:
{
"status": "success",
"data": {
"issuanceEvents": [
{
"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"
}
],
"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. |
issuanceEvents |
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. |
date |
String | ISO 8601 formatted date and time when the asset has been issued. |
hasMore |
Boolean | Indicates whether there are more asset issuance events that satisfy the search criteria yet to be returned. |
Possible errors
Status code | Error message |
---|---|
400 | 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.9/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.9/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
}
Request
GET /assets/:assetId
/holders
Parameters
- URL parameters:
assetId
: The ID of the asset to get holders.
- Query string parameters:
limit
: (optional, default:500
) Maximum number of list items that should be returned. Must be a positive integer value not greater than 500.skip
: (optional, default:0
) Number of list items that should be skipped (from beginning of list) and not returned. Must be a non-negative (includes zero) integer value.
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 | 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.9/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.9/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
}
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.9/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.9/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
}
Request
GET /permission/events/:eventName
/rights
Parameters
- URL parameters:
eventName
: The name of the permission event the permission rights set for which should be retrieved.
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 | 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.9/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.9/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
}
Request
POST /permission/events/:eventName
/rights
Parameters
URL parameters:
eventName
: The name of the permission event for which the permission rights should be set.
Request body:
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 |
Boolean | The value true indicating that the permission rights have been correctly set. |
Possible errors
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.9/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.9/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
}
Request
GET /permission/events/:eventName
/rights/:deviceId
Parameters
URL parameters:
eventName
: The name of the permission event the permission right set for which should be retrieved.deviceId
: The ID of the virtual device the permission right applied to which should be retrieved. Should be a device ID unlessisProdUniqueId
is set. The special valueself
can be used in place of the device ID of the virtual device issuing the request.
Query string parameters:
isProdUniqueId
: (optional, default:false
) Indicates whether the supplied ID is a product unique ID.
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 | 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.9/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.9/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
}
Request
GET /devices/:deviceId
Parameters
URL parameters:
deviceId
: The ID of the virtual device the identification info of which should be retrieved. Should be a device ID unlessisProdUniqueId
is set. The special valueself
can be used in place of the device ID of the virtual device issuing the request.
Query string parameters:
isProdUniqueId
: (optional, default:false
) Indicates whether the supplied ID is a product unique ID.
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 | 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.9/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.9/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
}
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.
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 |
final-msg-progress |
Progress of asynchronous message processing has come to an end |
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. |
Final progress of message processing (final-msg-progress)
Sample notification message:
{
"ephemeralMessageId": "hEXMdtTMzkhyJ4WssQmp",
"action": "read",
"progress": {
"bytesProcessed": 28,
"done": true,
"success": true,
"finishDate": "2019-03-13T14:09:10.121Z"
},
"result": {
"messageId": "mt7ZYbBYpM3zcgAf3H8X",
"continuationToken": "kjXP2CZaSdkTKCi2jDi2"
}
}
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
ephemeralMessageId |
String | The ID of the ephemeral message — either a provisional or a cached message — to which this notification refers. |
action |
String | The action that was to be performed on the message. One of: log , send , or read . |
progress |
Object | Current processing status. |
bytesProcessed |
Number | Total number of bytes of message that had already been processed. |
done |
Boolean | (should always be true ) Indicates that processing has finished. |
success |
Boolean | Indicates whether message has been successfully processed. |
error |
Object | (only returned if processing finished with error) Error information. |
code |
Number | Numeric code — equivalent to an HTML status code — of the error that took place while processing the message. |
message |
String | Text describing the error that took place while processing the message. |
finishDate |
String | ISO 8601 formatted date and time when processing was finalized. |
result |
Object | (only returned if processing finished successfully) Result of processing. |
messageId |
String | ID of the Catenis message. When logging or sending — action equals to log or send —, it is the ID of the resulting message. When reading — action equals to read —, it references the message being read. |
continuationToken |
String | (only returned if reading message — action equals to read ) The token that should be used to complete the read of the message. |
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
WebSocket notification message dispatcher
This notification message dispatcher uses a WebSocket connection as the communication transport for the notification channel.
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/0.9/notify/ws/:eventName
Parameters
- URL parameters:
eventName
: The name of the notification event for which a notification channel should be open.
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/0.9/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"
}
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.
Do not send the authenticated request, but rather just take the HTTP headers
X-BCoT-Timestamp
andAuthorization
contained in it and save them.Go ahead and open the WebSocket connection.
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. |
Authentication response
If a successful authentication message is not received by the WebSocket message dispatcher within 5 seconds after the WebSocket connection is established, the WebSocket connection is closed by the Catenis server.
Notification Channel Open message
After receiving a successful authentication message, the WebSocket message dispatcher will send a special message the
content of which is NOTIFICATION_CHANNEL_OPEN
.
This message is used to confirm that the WebSocket notification channel is open and ready to send notifications.
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. |
413 | Payload Too Large - The data sent with the request is too large and cannot be processed. |
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. Note that a deleted or inactive device will trigger this error. |
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. |
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 supplied ID is not a valid device ID or product unique ID, or there is no virtual device with that ID. |
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. |
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 or expired ephemeral message | The supplied ID is not a valid ephemeral message, or the asynchronous processing status cannot be retrieved for the given ephemeral message. |
Invalid or unexpected continuation token | The supplied ID is not a valid continuation token, or that is not the ID that Catenis Enterprise expects to continue processing the message. |
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 already complete | Catenis Enterprise has already received the full message's contents, and an additional message chunk cannot be accepted. |
Message already read | The message, which has been requested to be read asynchronously or in chunks, has already been fully read. |
Message expired | The maximum time expected for the next message chunk to be passed/retrieved has elapsed and Catenis Enterprise cannot fulfill the request. |
Message not available | The message, which has been requested to be read asynchronously, is not yet ready to be read. |
Message too large for reading at once | The contents of the message being read is too large for Catenis Enterprise to returned it in a single call. |
Message too long to be embedded | Request specified that message should be stored embedded in the blockchain transaction but it is too large (over 75 bytes unencrypted or 64 bytes encrypted) to fit in. |
No 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. |
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. |
Progress not available | Asynchronous processing status not yet available for the given ephemeral message. |
Request data too large to be processed | Catenis Enterprise refuses to process the request because the data sent with the request (typically a message's contents) is too large. |
System currently not available; please try again at a later time | Catenis Enterprise is not currently ready to process requests. |