LLSR API - Signing and Authenticating REST Requests

Note that the methods in this API require public and private keys. If you do not have API keys please visit support.skilouise.com and request them.

Custom HTTP Headers

The LLSR REST API uses HTTP headers to pass authentication information. Under the LLSR authentication scheme, the HTTP headers required are:

X-LLSR-Public
X-LLSR-Sig
X-LLSR-Timestamp

Developers are issued a public key and private key when they register. For request authentication, the X-LLSR-Public element represents
the developer's public key, and is used by the API to identify the requester and to look up the corresponding private key that was used to compute
the signature.

The X-LLSR-Sig element is an HMAC-SHA256 signature of the X-LLSR-Timestamp from the request. The X-LLSR-Sig part of the header
will vary from request to request. If the request signature calculated by the system matches the X-LLSR-Sig included with the request, the
requester will have demonstrated possession of the private key. The request will then be processed under the identity, and with the authority, of the
developer to whom the key was issued.

The element X-LLSR-Timestamp is used to identify when the request was made and to validate the time allowed before the request expires. The
timestamp should be generated at request time, and must be in the standard Unix format (seconds elapsed since the Epoch - midnight of Jan 1, 1970).

PHP Example

$api_url = "https://api.skilouise.com/scanning/validate/";
$season_pass = 'ABC12345';
$public_key = 'MY_PUBLIC_KEY';
$private_key = 'MY_PRIVATE_KEY';

$timestamp = time();
$sig = hash_hmac('sha256', $timestamp, $private_key);

$headers = array(
    'X-LLSR-Public: '.$public_key,
    'X-LLSR-Sig: '.$sig,
    'X-LLSR-Timestamp: '.$timestamp
);

$ch = curl_init($api_url.$season_pass);

curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,true);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, true);


$result = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$json_response = json_decode($result);

JAVA Example (using Unirest)

String publicKeyHeader = MY_PUBLIC_KEY;
Integer timeStampHeader= (int)(System.currentTimeMillis() / 1000L);
String sigHeader = hmacSha256(timeStampHeader.toString(), MY_PRVIATE_KEY);

String url = "https://api.skilouise.com/scanning/validate/";
String seasonPass = "ABC12345";
try 
{				            						
	HttpResponse<JsonNode> jsonResponse = Unirest.get(url+seasonPass)
			.header("accept", "application/json")
			.header("x-llsr-public",publicKeyHeader)
			.header("x-llsr-timestamp",timeStampHeader.toString())
			.header("x-llsr-sig",sigHeader)
			.asJson();
								      
	if(jsonResponse.getStatus() == 200)
	{
	      //you've got success response code so you can parse the return values.		      
	}
	else
	{
	      //an error has occurred. Get the error message.
	      JSONObject json =  jsonResponse.getBody().getObject();
	      JSONObject error = json.getJSONObject("error");
	      String errorMessage = error.getString("message");
	}
	
} 
catch(InterruptedException ex) 
{
	Thread.currentThread().interrupt();
}
		
public static String hmacSha256(String value, String key) 
{
	try 
	{
	    // Get an hmac_sha1 key from the raw key bytes
	    byte[] keyBytes = key.getBytes();           
	    SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA256");

	    // Get an hmac_sha256 Mac instance and initialize with the signing key
	    Mac mac = Mac.getInstance("HmacSHA256");
	    mac.init(signingKey);

	    // Compute the hmac on input data bytes
	    byte[] rawHmac = mac.doFinal(value.getBytes());

	    // Convert raw bytes to Hex
	    byte[] hexBytes = new Hex().encode(rawHmac);

	    //  Covert array of Hex bytes to a String
	    return new String(hexBytes, "UTF-8");
	} 
	catch (Exception e) 
	{
	    throw new RuntimeException(e);
	}
}	

JavaScript Example (using POSTMAN pre-script)

var publicKey = "{public-key}";
var privateKey = "{private-key}";

var requestTimeStamp = new Date().getTime()/1000;

const createHmacString = (ts, privateKey) => {
    const key = CryptoJS.enc.Utf8.parse(privateKey)
    const timestamp = CryptoJS.enc.Utf8.parse(ts)
    const hmac = CryptoJS.enc.Hex.stringify(CryptoJS.HmacSHA256(timestamp, key))
    return hmac;
}

const signature = createHmacString(requestTimeStamp, privateKey);

pm.request.headers.add({
  key: 'X-LLSR-Public',
  value: publicKey
});

pm.request.headers.add({
  key: 'X-LLSR-Sig',
  value: signature
});

pm.request.headers.add({
  key: 'X-LLSR-Timestamp',
  value: requestTimeStamp.toString()
});

HTTP Status Codes

The Authentication API uses the following standard HTTP status codes:

200: OK
400: Bad Request
401: Unauthorized
503: Service Unavailable