LEARNING

Getting Started with Circle REST API

This article will give you a brief introduction on how to use the Circle REST APIs. 

For details of each API Method, go to the API Reference.

Use Cases

Data Security, Control and Privacy

Circle REST API is an incredbly easy-to-implement yet powerful and flexible way to achive unrivaled data security, control and privacy. We are still learning all the ways it can be used ourselves, but have outlined some of the most popular ones here:

Credential-free Authentication

Credential-free authentication is a special kind of use case for Circle REST API. Circle Capsules can contain anything – files, databases, unstructured data. Your imagination is the only limit!   For credential-free authentication, you store secrets, tokens, cryptographic signatures, etc. in them.   For more advances use cases, you can store policies and even software to execute them.    You can learn more about that here:

We are already integrated and implementated this as a turn-key solution with:

and more are coming soon!

We also offer, however, Circle Access as complete, turn-key solution for Cryptographic Credential-free Authentication - it can literally be integrated in a few hours. If that is of interest, please see:

Identity

Circle-of-Trust is another example of how Circle REST API and our unique privacy and security architecture can be leveraged. You can implement your own, or use your out-of-the-box solution:

How Circle REST API Differs from other APIs

Circle REST API is fundamentally different than most traditional APIs you have worked with. This is because you only reach out to the Circle cloud one time, to get an authentication token.  After that you communicate with the Circle Service running on your local machine.

For example, the endpoint to get a Bearer Token is https://api.test-dev.gocircle.ai/api/token.  But to enumerate items in the Circle you call http://127.0.0.1:31415/v1/enumTopics.

The reason for this is Circle keeps keys on the local machine and not in the cloud.  So those cannot be sent to the cloud.  This is the whole premise upon which the system is built.

Now, you could do all the subsequent API calls using REST calls to localhost. But it's simpler to use the NodeJS SDK object.  (Plus we have one in C#.)

The code samples below use REST to get the token then the NodeJS SDK for further API calls.

Developer Credentials

When you sign up as a developer you get these developer credentials:

  • CustomerCode
  • AuthCode
  • AppKey
  • PrivateKey
  • PublicKey
  • Secret

Download the Circle Service

You need to have the Circle Service running on your local machine. 

Download the installer for your platform:

Installation

macOS

Install the CircleService.pkg. This installer may request your credentials more than once because it installs some certificates.

Windows

Install CircleSvrSetup.exe. You may need to restart your computer.

Testing

After installation, the Circle Service will be running as a Service Application for Windows and as a User Agent for macOS.
To check if everything went right, open a Web Browser and visit the website. http://127.0.0.1:31415/. If it is running correctly you will see a simple text message.

Your first application

To build your first application create the file firstapp.html and copy the following content:

<title>First CircleService App</title>
<h2 class="betterdocs-content-heading" id="1-toc-title">My First CircleService App </h2>
<p id="runningResult"></p>					
				

Now create a file firstapp.js and insert this content:

async function checkCircleServiceIsRunning() {
  let isRunning = await Circle.isServiceRunning();
  if (isRunning) {
    document.getElementById('runningResult').innerText = 'CircleService is running!';
  } else {
    document.getElementById('runningResult').innerText = 'Can not find CircleService!';
  }
}
(function() {
  checkCircleServiceIsRunning();
})();					
				

Now open the firstapp.html in your browser and you should see this page:

If CircleService is not running, you will see the message "Cannot find CircleService!" instead.

Getting a Bearer Token

To use the Circle APIs you must first get a Bearer Token.
This is basically the way you login to Circle and persist an API session.  Circle takes your customer ID, APP Key, and the other parameters shown below and issues the token.  It authenticates you. Then you present it in the header in subsequent API calls.
You can use the token until it expires.
You use the endpoint https://api.test-dev.gocircle.ai/api/token? to get a Bearer Token.

ArgumentDescription
CUSTOMER_IDCustomer ID
APP_KEYAppKey
USER_IDUserId
TIMESTAMP

Epoch Time in seconds.

SIGNATURE

See below for details.  Basically, it is the SHA256 hash of the URL parameters.

Code Example

Here is a JavaScript example of how to get a token.  Below we explain the code.

import fetch from 'node-fetch';
import crypto from 'crypto';
var encryptData = function (dataToEncrypt) {
    return crypto.createHmac('sha256', process.env.SECRET.trim()).update(dataToEncrypt).digest('base64');
}
   let timeStamp = Math.floor(Date.now() / 1000);
    let urlParameters = `customerId=${process.env.CUSTOMER_ID}&amp;appKey=${process.env.APPKEY}&amp;endUserId=${process.env.USER_ID}`;
   urlParameters += '&amp;nonce=' + timeStamp;
   let signature = encryptData(urlParameters);
   fetch("https://api.test-dev.gocircle.ai/api/token?" + urlParameters + '&amp;signature=' + signature, {
                 method: 'GET',
                 headers: {
                   headers: 'Content-Type: application/json'
   }
   }).then(response =&gt; response.json())
    .then (response =&gt; {
        console.log(response);
   }).catch(function (error) {
      console.log("error ", error);
    });					
				
{"Token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IkSUNJakFOQmdrcWhraUc5d....
01NTDUN7NwmclE","Expiry":"2021-11-19T10:50:06.8173414Z"}					
				

Calculating the Signature

The last URL query parameter is a SHA256 hash calculated over the other parameters.  

This hashing technique is called a signature.   (A signature is a standard cryptographic way of verify that the document came from you, versus someone pretending to be you. To understand that, think of signing a check or other document with a pen.  It's the same concept.)

You create the signing using a SHA256 hash function with your secret.   Then you base64 encode it.   (Base64 encoding is like URL encoding: it ensures that the signature only includes characters that are valid in the URI.)

The secret was given to you when you signed up for developer credentials.

You add the signature to the end of the URL query parameters by adding another parameter:

'&amp;signature=' + signature					
				

Example Signature

Given this customerID, appKey, userId, and time (nonce):

const dataToEncrypt = "?customerId=ABC123&amp;appKey=appKey_QWERTYUIOP1234567890&amp;endUserId=myUserId&amp;nonce=1234567890";					
				

You calculate the signature like this:

const crypto = require('crypto');
crypto.createHmac('sha256', process.env.SECRET.trim()).update(dataToEncrypt).digest('base64');					
				

Further Reading

For more HMAC SHA256 Base64 examples please visit Joe Kampschmidt's Code or Google Maps URL Signing Samples.
For online crypto testing you can visit DevLang and use Output Text Format as Base64.

Authorizing

With the token, now you can initialize the CircleSDK and authorize the token:

let iniResult = await Circle.initialize(appKey, token);
if (iniResult &amp;&amp; iniResult.Status.Result) {
  // CircleService is running and token is authorized
}					
				

Circle.initialize is a method available for JavaScript CircleSDK that is NEEDED to be called, before you make any request. It checks if CircleService is running (Circle.isServiceRunning), and then calls CircleService's authorize (Circle.authorize).

Getting Data

The client now has a valid and authorized token, and you can start retrieving data from CircleService like these examples:

 

enumCircles

List all joined Circles using your CustomerCode:

let enumResult = await Circle.enumCircles();
if (enumResult &amp;&amp; enumResult.Status.Result) {
  let circles = enumResult.CircleMeta;
  //do your stuff
}					
				

 

enumTopics

List all joined Topics using a CircleId got from enumCircles above:

let enumResult = await Circle.enumTopics(CircleId);
if (enumResult &amp;&amp; enumResult.Status.Result) {
  let topics = enumResult.Topics;
  //do your stuff
}					
				

 Understanding Circle