API Authentication
API requests made in System Owner or Agent mode require authorization.
In System Owner mode, the API User account is granted full access to sensitive customer data , including names, addresses, payment info, etc. Given this access, any API requests made on System Owner mode require authentication which needs to be uniquely generated with each request.
In Agent mode, information may change on a per-agent basis, so authentication is also required.
Due to the nature of the Headers required in the API request, it is not possible to send Authenticated calls client-side
Spektrix has been authorized by our clients to process and manage their data in an appropriate and secure manner. By gaining access to our API you will have access to this data and are therefore also responsible for using it appropriately and securely.
The Spektrix API has been designed with security in mind. We use industry standard SSL encryption to protect data in transit and access to sensitive data and some functionality requires authentication.
Signing and Authenticating Requests
Authenticated API requests will require an API Login Name and must be signed with your API Secret Key. These can be obtained from a Spektrix User who has Settings Administrator access to the system in question. Our Support Centre has articles on how to set up an API user.
The request requires three headers of Host, Date and Authorization; the signature needs to match with what is generated on Spektrix servers to be accepted.
GET api/v3/customers/I-AK11-1ATK
Host: system.spektrix.com
Date: Mon, 21 Oct 2020 07:28:00 GMT
Authorization: SpektrixAPI3 TestLogin:frJIUN8DYpKDtOLCwo//yllqDzg=
The Date header time must be in UTC timezone
Constructing the Authorization Header
Overview
Below you can find the pseudocode on how to construct the Authorization Header. You can use it as a basis for whatever language you are using.
BodyStringToSign = BASE-64( MD5( UTF-8( body ) ) ); // This is only required if sending a request with a body, e.g., non-GET requests
StringToSign = HTTP-Method
+ "\n" + HTTP-Uri
+ "\n" + HTTP-Date
+ [ "\n" , BodyStringToSign ]; // This part should not be included in GET requests
Signature = BASE-64-ENCODE( HMAC-SHA1( BASE-64-DECODE(SecretKey), UTF-8( StringToSign ) ) );
Authorization = "SpektrixAPI3 " + LoginName + ":" + Signature;
Algorithm
- If the request has a body (all requests apart from GET) construct BodyStringToSign as follows:
- UTF-8 encode the contents of the request body;
- Calculate the MD5 sum of the result, returned in raw binary format with a length of 16 bytes;
- Base-64 encode the MD5 sum.
- Construct StringToSign by appending:
- the HTTP method (in upper case);
- A newline ("\n");
- The URI;
- A newline ("\n");
- The contents of the Date header; (preferred format is RFC 7231, eg: Mon, 21 Oct 2020 07:28:00 GMT )
- If there is a body (all requests apart from GET) a newline ("\n"), and then BodyStringToSign.
- Construct Signature as follows:
- UTF-8 encode StringToSign;
- Base-64 decode the Secret Key;
- calculate the SHA1 HMAC of the utf-8 encoded string using the base64-decoded Secret Key, returned in raw binary format with a length of 20 bytes;
- Base-64 encode the SHA1 HMAC result.
- Finally, form the Authorization header value by appending
- "SpektrixAPI3";
- a space;
- your API login name;
- a colon (" : ");
- and the Signature string calculated as above.
Example Calls
Below are examples of how to implement generation of the required headers (including the Authorization) to make calls in Owner mode. Please note that while we have used these scripts and can verify they do work, we have a limited capacity to aid in troubleshooting or implementating them into specific frameworks that you may require.
- JavaScript (Node)
- PHP
import fetch from 'node-fetch'
import crypto from 'node:crypto'
// Set these accordingly
const requestUrl = 'https://system.spektrix.com/clientname/api/v3/events'
const httpMethod = 'GET'
const apiBody = JSON.stringify({})
const apiUser = 'apiUsername'
const apiKey = 'apiSecretKey'
// Generate date for use in signature generation and header
const date = new Date().toUTCString()
// Generate authorization header
let signature = `${httpMethod}\n${requestUrl}\n${date}`;
if (httpMethod !== 'GET') {
let contentHash = crypto.createHash('md5').update(apiBody, 'utf8').digest();
let encodedContentHash = contentHash.toString('base64');
signature = `${signature}\n${encodedContentHash}`;
}
const decodedSecret = Buffer.from(apiKey, 'base64');
const hash = crypto.createHmac('sha1', decodedSecret);
hash.update(signature);
const encodedHash = hash.digest('base64');
const authorizationHeader = `SpektrixAPI3 ${apiUser}:${encodedHash}`;
// Make API call
const response = await fetch(requestUrl, {
method: httpMethod,
// Add required headers
headers: {
"Authorization": authorizationHeader,
"Content-Type": 'application/json',
"Host": 'system.spektrix.com',
"Date": date
},
body: apiBody
})
const data = await response.json()
console.log(data)
<?php
//Set these accordingly
$requestUrl = 'https://system.spektrix.com/clientname/api/v3/events';
$httpMethod = 'GET';
$apiUser = 'apiUser';
$apiKey = 'apiKey';
$dateTime = gmdate('D, d M Y H:i:s T');
$signatureString = $httpMethod . "\n" . $requestUrl . "\n" . $dateTime;
if ($httpMethod !== 'GET') {
//Set $body accordingly
$body = '';
$md5 = md5($body, true);
$md5 = base64_encode($md5);
$signatureString = $signatureString . "\n" . $md5;
}
$signedString = hash_hmac('sha1', $signatureString, base64_decode($apiKey), true);
$signature = base64_encode($signedString);
$headers = array();
$headers[] = 'Date: ' . $dateTime;
$headers[] = 'Authorization: SpektrixAPI3 ' . $apiUser . ':' . $signature;
// Make API call
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $requestUrl);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
//Add requested headers
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_exec($ch);
curl_close($ch);
?>
Signature tool for testing
This signature testing tool, currently in Beta phase, has been developed to help you with constructing your header. Please note it is for testing purposes only and you will need to rotate your API keys after using it for security purposes.
This tool only checks the algorithm and does not make an actual request. This means it does NOT validate any of the following:
- the request is valid
- custom domain or URL are working properly
- the secret is correct
- your system clock is synchronised properly