Skip to main content
NICE CXone Expert
Expert Success Center

Use a Server API Token With an Integration

Applies to:
All MindTouch Versions
Role required:
Admin
Instructions and examples to validate your Server API Token in order to gain access to the Expert API.

What You will Need

You should have recorded the following when generating your Server API Token:  

  • Key
  • Secret

How to Use Your Server API Token

To gain access to the Expert API, you first need to provide a Server API Token signature to Expert. Your token signature will be in the following format:

tkn_{key}_{epoch}_{user}_{hash}

Server API Token Signature Breakdown

key Provided with your Server API Token
epoch The current time in Unix timestamp (for example Current time: 02/03/2015 @ 5:10am (UTC); Unix timestamp: 1422940200)
user An Expert user id or username prefixed with `=` (for example =admin). The API request will be handled in the context of this user identity
hash Expert requires HMAC SHA256 hashing of server API tokens. The benefit of HMAC SHA256 over plain SHA256 is it provides Expert the ability to detect if the token signature has been tampered with since being generated by your server

The signature is included in an API request by setting it as the X-Deki-Token HTTP header value. Upon receipt, Expert calculates the same signature and matches it to the signature received. Once validated, your integration can access the Expert API.

Your authentication signature is time-sensitive (5 minutes), and as a common best practice, it's advisable to generate a new token for each API call. If a request is processed too long after the timestamp is created, it may be denied.

Examples

The following are code snippets for PHP, C#, Node.js, and Python to get you started:

Java Example

// Server API Token key and secret are available from API token management dashboard when Server API Token is generated
String key = "REPLACE_KEY";
String secret = "REPLACE_SECRET";

// include username prefixed with '='
String user = '=foo';

// ...or include userid
String user = '123';

// hash time, key, user with secret
String epoch = Long.toString(new Date().getTime() / 1000L);
try {
    Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
    SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
    sha256_HMAC.init(secret_key);
    String message = key + "_" + epoch + "_" + user;

    // this example uses Apache Commons Codec (https://commons.apache.org/proper/commons-codec/) to ensure bytes are converted to a HTTP header compatible hex string
    hash = Hex.encodeHexString(sha256_HMAC.doFinal(message.getBytes()));
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
    
    // handle signing exceptions
}
String token = String.join("_", "tkn", key, epoch, user, hash);

// send signature as X-Deki-Token HTTP header to MindTouch API
URL url = new URL("https://success.example.com/@api/deki/pages/home/info");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("X-Deki-Token", token);

PHP Example

<?php

// Server API Token key and secret are available from API token management dashboard when Server API Token is generated
$key = 'REPLACE_KEY';
$secret = 'REPLACE_SECRET';

// include username prefixed with '='
$user = '=foo';

// ...or include userid
$user = '123';

// hash time, key, user with secret
$epoch = time(); 
$hash = hash_hmac('sha256', ("{$key}_{$epoch}_{$user}"), $secret, false);
$token = "tkn_{$key}_{$epoch}_{$user}_{$hash}";

// send signature as X-Deki-Token HTTP header to MindTouch API (a fictional HTTP client is used in this example)
$client = new HttpClient('https://success.example.com/@api/deki/pages/home/info');
$client = $client->withHeader('X-Deki-Token', $token);
$response = $client->get();

C# Example

using System;
using System.IO;
using System.Security.Cryptography;
using System.Net.Http;

// Server API Token key and secret are available from API token management dashboard when Server API Token is generated
var key = "REPLACE_KEY";
var secret = "REPLACE_SECRET";

// include username prefixed with '='
var user = "=admin";

// ...or include userid
user = "1";

// hash time, key, user with secret
var hash = "";
var epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
using (var hmac = new HMACSHA256(Encoding.ASCII.GetBytes(secret)))
{
    var bytes = hmac.ComputeHash(Encoding.ASCII.GetBytes(string.Format("{0}_{1}_{2}", key, epoch, user)));
    hash = BitConverter.ToString(bytes).Replace("-", "");
}
var signature = string.Format("tkn_{0}_{1}_{2}_{3}", key, epoch, user, hash);

// send signature as X-Deki-Token HTTP header to MindTouch API (WebRequest is used in this example)
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Deki-Token", signature);
var response = await client.GetAsync("https://authtalk.mindtouch.es/@api/deki/users/current?dream.out.format=json");
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);

// Exchange signature token for a user's authtoken for immediate access via a link.
// https://{authtalk.mindtouch.es}/@api/deki/users/authenticate?x-deki-token={signature}
Console.WriteLine($"https://authtalk.mindtouch.es/@api/deki/users/authenticate?x-deki-token={signature}");

Console.WriteLine($"https://authtalk.mindtouch.es/@api/deki/users/authenticate?x-deki-token={signature}&redirect=https%3A%2F%2Fauthtalk.mindtouch.es%2F");

Node.js Example

// Server API Token key and secret are available from API token management dashboard when Server API Token is generated
const key = 'REPLACE_KEY';
const secret = 'REPLACE_SECRET';

// include username prefixed with '='
let user = '=foo';

// ...or include userid
let user = '123';

// hash time, key, user with secret
const crypto = require('crypto');
const hmac = crypto.createHmac('sha256', secret);
const epoch = Math.floor(Date.now() / 1000);
hmac.update(`${key}_${epoch}_${user}`);
const hash = hmac.digest('hex');
const token = `tkn_${key}_${epoch}_${user}_${hash}`;

// send signature as X-Deki-Token HTTP header to MindTouch API (https://github.com/request/request is used in this example)
const request = require('request');
request({
  url: 'https://success.example.com/@api/deki/pages/home/info',
  headers: {
    'X-Deki-Token': token
  }
}, (error, response, body) => {

  // ...
});

Python 3 Example

import hashlib
import time
import requests
import hmac

# Server API Token key and secret are available from API token management dashboard when Server API Token is generated
key = 'REPLACE_KEY'
secret = 'REPLACE_SECRET'

# include username prefixed with '='
user = '=foo';

# ...or include userid
user = '123';

# hash time, key, user with secret
epoch = str(int(time.time()))
message_bytes = f'{key}_{epoch}_{user}'.encode('utf-8')
secret_bytes = secret.encode('utf-8')
hash = hmac.new(secret_bytes, message_bytes, digestmod=hashlib.sha256).hexdigest().lower()
token = f'tkn_{key}_{epoch}_{user}_{hash}'

# send signature as X-Deki-Token HTTP header to MindTouch API (Python Requests is used in this example)
headers = {
   'X-Deki-Token': token,
}
response = requests.get('https://success.example.com/@api/deki/pages/home/info', headers=headers, verify=False)

# Handling the response
if response.status_code == 200:
    # Success
    print(response.text)
else:
    # Error
    print(f"Error: {response.status_code} - {response.text}")

Postman Example

In pre-request script:

// Server API Token key and secret are available from API token management dashboard when Server API Token is generated
const key = 'REPLACE_KEY';
const secret = 'REPLACE_SECRET';

// include username prefixed with '='
let user = '=admin';

// ...or include userid
let user = '123';

const epoch = Math.floor(Date.now() / 1000);
var hash = CryptoJS.HmacSHA256(`${key}_${epoch}_${user}`, secret);
const token = `tkn_${key}_${epoch}_${user}_${hash}`;
pm.request.headers.add({
    key: 'x-deki-token',
    value: token
});

Authenticate With a Server API Token

This authentication method should only be used to implement Single Sign-On if it is not possible to leverage Expert's supported enterprise-grade OpenID Connect or SAML SSO solutions.

A Server API Token signature can be traded for an Auth Token session cookie, which will sign in a user. Using this method, you can construct a URI that logs the user in and redirects to any page in Expert. To tell the API to issue an Auth Token session cookie, use the following format to create a URI for the user to follow:

GET https://{hostname}/@api/deki/users/authenticate?x-deki-token={signature}&redirect={redirect}
  • {hostname} is the hostname of the Expert site
  • {signature} is the server API token signature
  • {redirect} is a URI for the user to be redirected to (for example redirect=https://example.com/foo). This URI must be URI encoded

Since this URI is valid for only a few minutes, it should not be generated as a URI on one of your pages directly. Instead, it should be a redirect response of a request to your server that authenticates the user in your system. The system should build the URI at the time of request. After the user follows the URI, if the authentication is successful they receive HTTP response headers similar to the following:

HTTP/1.1 302 FOUND
Date: Thu, 28 Feb 2013 19:58:59 GMT
Server: Dream-HTTPAPI/2.4.0.393
X-Deki-Site: id="{site}"
X-Deki-Session: {session}
Content-Type: text/plain; charset=us-ascii
Content-Length: 20
Location: {redirect}
Set-Cookie: authtoken="{authtoken}"; Domain=.{hostname};
Set-Cookie: dekisession="{session}"; Domain=.{hostname};

This results in a sign in workflow like this:

  1. A user logged into your authentication system clicks a URI to go to the Expert site. Note: the URL actually points to an endpoint on your site.
  2. Your endpoint validates the user's credentials.
  3. Your endpoint constructs the Server API Token signature and the redirect URI above.
  4. Your endpoint responds with a 302 Found response and the constructed URI as its Location Header.
  5. The user's browser redirects to the Expert API.
  6. The Expert API creates the user as a Community Member if they do not exist on Expert site, and issues a 302 Found response including the Auth Token session cookie and the Location Header for {redirect}.
  • Was this article helpful?