We’ve migrated our documentation to a new site, which means some URLs have changed.
Audience

API authentication

See also:

Most of the JSON API methods require authentication. The only exceptions to this rule is for methods under the path prefix /public/ which do not require authentication. Authentication is a prerequisite for being able to do authorization, i.e., to be able to verify that the callee actually has the required permissions to access the requested data.

This page describes the technical details of the authentication mechanism and how to use this from various programming languages.

If all you want is to use the API from the command line by our "cx.py" utility, see the guide on how to get started and the utilities therein.

HTTP headers

Authentication is done by including a single HTTP header named X-cXense-Authentication with the request. This header includes the user name, the current date as well as a HMAC signature of the given date parameter. The date parameter is used to verify that the request will only be valid for a short period of time, so it's important that the client has a synchronized clock with the correct timezone set. Alternatively, the client can make a request to the unauthenticated /public/date API method which will return the current date as part of the response.

The format of the X-cXense-Authentication header is:

username=<username> date=<date> hmac-sha256-<encoding>=<signature>

The indicated placeholder values are as follows:

Value

Description

<username>

The email address you use when you sign in to https://insight.cxense.com.

<date>

The current date and time in ISO 8601 extended format for complete representation for calendar dates.

<encoding>

Describes how <signature> has been encoded. Can be either hex or base64.

<signature>

The encoded HMAC SHA256 signature, using the API key corresponding to <username> as the key, and <date> as the message.

Click on your user-login name in the top right corner of in to https://insight.cxense.com to get your API key.


The API key is not exposed to all users when they are created. It is enabled on request.

Persisted requests

Persisted, authenticated requests for use in widgets on public web pages are supported. The requests are created by an authenticated user giving a path and a request parameter object. Unauthenticated users can then execute these requests by providing the persisted request identifier. The request will be run using credentials of the creating user, and can not be modified in any way by the executor. This allows you to display a subset of the data available to you on your website, without fear that additional data can be queried using the stored credentials. As the request identifier is a large random string that is only known to the creator, only those who are given the identifier by the creator will be able to execute it.

Read more about how to create and execute persisted requests in /persisted/create.

Python example

The example below shows how API authentication can be done from a Python program.

#!/usr/bin/python
 
import datetime
import hashlib
import hmac
import httplib
import json
 
def cx_api(path, obj, username, secret):
    body = json.dumps(obj)
    date = datetime.datetime.utcnow().isoformat() + "Z"
    signature = hmac.new(secret, date, digestmod=hashlib.sha256).hexdigest()
    headers = {"X-cXense-Authentication": "username=%s date=%s hmac-sha256-hex=%s" % (username, date, signature)}
    headers["Content-Type"] = "application/json; charset=utf-8"
    connection = httplib.HTTPSConnection("api.cxense.com", 443)
    connection.request("POST", path, json.dumps(obj), headers)
    response = connection.getresponse()
    return response.status, json.load(response)

if __name__ == "__main__":
    username = "YOUR USER NAME"
    secret = "YOUR API KEY"
	print(cx_api("/site", {"siteId": "YOUR SITE ID"}, username, secret))


#!/usr/bin/python
 
import datetime
import hashlib
import hmac
import http.client
import json

def cx_api(path, obj, username, secret):
    date = datetime.datetime.utcnow().isoformat() + "Z"
    signature = hmac.new(secret.encode('utf-8'), date.encode('utf-8'), digestmod=hashlib.sha256).hexdigest()
    headers = {"X-cXense-Authentication": "username=%s date=%s hmac-sha256-hex=%s" % (username, date, signature)}
    headers["Content-Type"] = "application/json; charset=utf-8"
    connection = http.client.HTTPSConnection("api.cxense.com", 443)
    connection.request("POST", path, json.dumps(obj), headers)
    response = connection.getresponse()
    status = response.status
    responseObj = json.loads(response.read().decode('utf-8'))
    connection.close()
    return status, responseObj

if __name__ == "__main__":
    username = "YOUR USER NAME"
    secret   = "YOUR API KEY"
    print(cx_api("/site", {"siteId": "YOUR SITE ID"}, username, secret))

Java example

The example below shows how API authentication can be done from a Java program. The example contains a static getAuthenticationHeader() method that can be used with any HTTP library that supports setting headers. In addition, a simplistic main method showing the usage with java.net.URLConnection is included.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Formatter;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.ISODateTimeFormat;
 
public class AuthenticationExample {
    public static String getAuthenticationHeader(String username, String secret) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
        String date = ISODateTimeFormat.dateTime().print(new DateTime(DateTimeZone.UTC));
        mac.update(date.getBytes("UTF-8"));
        byte[] signature = mac.doFinal();
        Formatter hex = new Formatter();
        for (byte b : signature) {
            hex.format("%02X", b);
        }
        return "username=" + username + " date=" + date + " hmac-sha256-hex=" + hex;
    } 
    public static void main(String[] args) throws Exception{
        URLConnection connection = new URL("https://api.cxense.com/site?json=%7B%7D").openConnection();
        connection.setRequestProperty("X-cXense-Authentication", getAuthenticationHeader("YOUR USER NAME", "YOUR API KEY"));
        connection.connect();
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        System.err.println(reader.readLine());
    }
}

C# example

The example below shows how API authentication can be done from a C# console application. The application returns information about a particular site.

using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
 
namespace Cxense
{
    class Program
    {
        static void Main(string[] args)
        {
            string user = "<Your user here>";
            string apiKey = "<Your api key here>";
            string siteId = "<Your site id here>";
            string apiUrl = "https://api.cxense.com/site"; 
            var date = DateTime.UtcNow.ToString("o");
            var hmacsha256 = new HMACSHA256(Encoding.UTF8.GetBytes(apiKey));
            var hmac = hmacsha256.ComputeHash(Encoding.UTF8.GetBytes(date));
            var hmacHex = hmac.Aggregate(new StringBuilder(32), (sb, b) => sb.Append(b.ToString("X2"))).ToString();
            WebRequest request = WebRequest.Create(apiUrl);
            request.ContentType = "application/json";
            request.Headers.Add("X-cXense-Authentication", "username=" + user + " date=" + date + " hmac-sha256-hex=" + hmacHex);
            request.Method = "POST"; 
            string query = "{\"siteId\":\"" + siteId + "\"}";
            byte[] byteArray = Encoding.UTF8.GetBytes(query);
            request.ContentLength = byteArray.Length;
            try
            {
                Stream dataStream = request.GetRequestStream();
                dataStream.Write(byteArray, 0, byteArray.Length);
                dataStream.Close();
                WebResponse response = request.GetResponse();
                using (var reader = new StreamReader(response.GetResponseStream()))
                {
                    string result = reader.ReadToEnd();
                    reader.Close();
                    Console.WriteLine(result);
                } 
                response.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            } 
            Console.ReadKey();
        }
    }
}

Node.js example

The example below shows how API authentication can be done from a Node.js console application.

var request = require('request'),
    crypto = require('crypto');

var username = 'username',
    apiKey = 'apiKey';

var date = new Date().toISOString(),
    hmac = crypto.createHmac('sha256', apiKey).update(date).digest('hex');

request.post({
    url: 'https://api.cxense.com/traffic/event',
    headers: { 'X-cXense-Authentication': 'username=' + username + ' date=' + date + ' hmac-sha256-hex=' + hmac },
    body: { 'start': -3600, 'siteId': '1234567890' },
    json: true
}, function (error, response, body) {
    if (!error && response.statusCode === 200) {
        console.log('The event group count: ' + body.groups.length);
    }
});

Google App Script example

/*
HELPER FUNCTION
*/
function hexdigest(bytearray) {
  // howto convert bytearray to hexstring
  // http://stackoverflow.com/a/34111253/1104502
  return bytearray.map(function(b) {return ("0" + (b < 0 && b + 256 || b).toString(16)).substr(-2)}).join("")
}
 
var username = 'username',
      apiKey = 'apiKey';
 
var date = new Date().toISOString();
var hmac = hexdigest(Utilities.computeHmacSha256Signature(date, apiKey));
var payload = { start: -3600, siteId: '1234567890' };
var url = 'https://api.cxense.com/traffic/event';
var params = {
    // don't mute HTTP exceptions
    'muteHttpExceptions': false,    
    'method': 'post',
    'contentType': 'application/json',
    'headers': { 'X-cXense-Authentication': 'username=' + username + ' date=' + date + ' hmac-sha256-hex=' + hmac },
    // Convert the JavaScript object to a JSON string.
    'payload': JSON.stringify(payload),
  };
 
var response = UrlFetchApp.fetch(url, params); 
// get status and data from HTTPResponse object

PHP example

The example below shows how API authentication can be done from a PHP program. The example works for PHP version > 5.1.2 due to the usage of the hash_hmac function. There are two blocks of debug output for testing.

<?php
$username="YOUR USERNAME";
$apikey="YOUR APIKEY";
$date = date("Y-m-d\TH:i:s.000O");
$signature=hash_hmac("sha256", $date, $apikey);
$url = 'https://api.cxense.com/traffic/event';
$plainjson_payload = "{\"start\":-3600, \"siteId\":\"YOUR SITEID\"}";
$options = array(
    'http' => array(
        'header'  => "Content-Type: application/json; charset=UTF-8\r\n".
                     "X-cXense-Authentication: username=$username date=$date hmac-sha256-hex=$signature\r\n",
        'method'  => 'POST',
        'content' => $plainjson_payload,
    ),
);
$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);
var_dump($result);
?>

Perl example

The example below shows how API authentication can be done from a Perl program. 

#!/usr/bin/perl -w

use LWP;
use strict;
use warnings;
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
use REST::Client;
use Digest::SHA qw(hmac_sha256_hex);
use Datetime;
use Data::Dumper;

my $browser = LWP::UserAgent->new;
my $username = 'YOUR USERNAME';
my $apikey = 'YOUR APIKEY';
my $SITEID = 'YOUR SITEID'; 
my $dt = DateTime->now();
$dt .= '.000000Z';
my $digest = hmac_sha256_hex($dt,$apikey);
my $p_json_payload = "{\"start\":-3600, \"siteId\":\"$SITEID\"}";
my $restUrl = 'https://api.cxense.com/traffic/event';

my $headers = {
        'Content-Type' => 'application/json',
        'Accept' => 'application/json', 'X-cXense-Authentication' => "username=$username date=$dt hmac-sha256-hex=$digest"
};

my $restClient = REST::Client->new();
$restClient->request('POST', "$restUrl", "$p_json_payload", $headers);
print $restClient->responseContent();

Ruby example

The example below shows how API authentication can be done from a Ruby program. 

#!/usr/bin/ruby -w
 
require "rubygems"
require "rest-client"
require "openssl"

digest = OpenSSL::Digest::SHA256.new
secret = "YOUR APIKEY"
uname = "YOUR USERNAME"
siteid = "YOUR SITEID"
resturl = "https://api.cxense.com/traffic/event"
payload = "{\"start\":-3600, \"siteId\":\"" + siteid + "\"}"
timetoseed = Time.now.utc
string_to_sign = timetoseed.strftime("%FT%R") + ":02.000000Z"
signature = OpenSSL::HMAC.hexdigest(digest, secret, string_to_sign)
auth_header = "username=" + uname + " date=" + string_to_sign + " hmac-sha256-hex=" + signature
response = RestClient.post(resturl, payload, :content_type => :json, :accept => :json, :'X-cXense-Authentication' => auth_header)
puts response.code
puts response.body


Swift example

The example below shows how API authentication can be done from a Swift 3 program. 

import Alamofire
import CryptoSwift
...
func AuthenticationHeaderString(for username: String, and apiKey: String) -> String {
    let df = DateFormatter()
    df.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
    let currentDate = df.string(from: Date())
    let pwd = try! HMAC(key: apiKey, variant: .sha256).authenticate("\(currentDate)".utf8.map {$0})
    return "username=\(username) date=\(currentDate) hmac-sha256-base64=\(pwd.toBase64()!)"
}
...
 
let userName = "<# YOUR USERNAME #>"
let apiKey = "<# YOUR APIKEY #>"
 
let headers: HTTPHeaders = [
    "Accept" : "application/json",
    "Content-Type" : "application/json",
    "X-cXense-Authentication": AuthenticationHeaderString(for: userName, and: apiKey)
]

Alamofire.request("https://api.cxense.com/profile/user", 
                  method: .post, 
                  parameters: ["id":"123456789","type":"cx"], 
                  encoding: JSONEncoding.default, 
                  headers: headers).responseJSON { (response) in
    print("JSON Response: \(response)")
}


Last updated: