Skip to content

Authentication

The API requires all requests to provide an authentication token in the x-icmr-auth-1 request header.

Take the following values.

api_access_keyThe API access key id (aka kid) provided to you.
timestampThe current UTC time in yyyyMMdd.HHmmss.SSS format.
nonceRandom sequence of characters generated with each request.

Concatenate the above strings, separated by space, to build the request_token.

request_token = f"{api_access_key} {timestamp} {nonce}" 

Then determine the following values:

http_methodThe HTTP method of the request in full capital letters (e.g. GET, POST, PUT, DELETE)
request_pathThe path of the request uri, including query string parameters
content_lengthThe value of the Content-Length header if present in the request or a single dash "-" character otherwise.
content_typeThe value of the Content-Type header if present in the request or a single dash "-" character otherwise.

Build the request_metadata_token by concatenating the above strings, separated by space.

request_metadata_token = f"{http_method} {request_path} {content_length} {content_type}"

Then build the unsigned_authentication_token as follows:

unsigned_authentication_token = f"{request_token} - {request_metadata_token}"

To compute the request_signature take the UTF-8 encoded bytes of the unsigned_authentication_token and sign them using the HMAC-SHA265 algorithm using the UTF-8 encoded bytes of your api_secret_key (aka shs) as the signing key and then compute the Base64 representation of the resulting byte array.

signature = hmac.new(
    api_secret_key.encode('utf-8'),
    unsigned_authentication_token.encode('utf-8'),
    hashlib.sha256
).digest()
request_signature = base64.b64encode(signature).decode('utf-8')

Finally compute the authentication_token by concatenating the request_token and the request_signature, again separated by a single space " " character.

authentication_token = f"{request_token} {request_signature}"

Send the authentication_token in the x-icmr-auth-1 header of the request.

{http_method} {request_path} HTTP/1.1  
host: {host} 
x-icmr-auth-1: {authentication_token}
Content-Type: {content_type}
Content-Length: {content_length}

Server clock synchronization

The instantCMR API requires the timestamp to be within 15 minutes of the API server clock to prevent replay attacks. Should the difference be bigger the API will return a 401 Request time too skewed response, including an x-icmr-auth-1 header with the current server timestamp. The client should parse back the server timestamp, compare it to its own clock and adjust its timestamp accordingly in subsequent requests.

Example

Let's assume we want to send the following request using our sample credentials.

GET /v3/igr/dub/foo/bar/receive?expire=5&recid=00001 HTTP/1.1  
host: api.instantcmr.com  
api_access_keyoh91tDqJySK8wur2V6ZNhg
api_secret_keyHPlkr8Bwh0OESa7B8Lw4t5k_yWg56ap7dsHEGUPaYU
http_methodGET
request_path/v3/igr/dub/foo/bar/receive?expire=5&recid=00001
content_length-
content_type-

Steps to compute the x-icmr-auth-1 header.

import hmac
import hashlib
import base64
import datetime
import uuid

# API credentials
api_access_key = 'oh91tDqJySK8wur2V6ZNhg'
api_secret_key = 'HPlkr8Bwh0OESa7B8Lw4t5k_yWg56ap7dsHEGUPaYU'

# Generate timestamp and nonce in the reqested format
timestamp = datetime.datetime.utcnow().strftime('%Y%m%d.%H%M%S.%f')[:-3]
nonce = str(uuid.uuid4())

# Request details
http_method = 'GET'
request_path = '/v3/igr/dub/foo/bar/receive?expire=5&recid=00001'
host = 'api.instantcmr.com'
content_type = '-'
content_length = '-'

# Create the x-icmr-auth-1 header
request_token = f"{api_access_key} {timestamp} {nonce}"
request_metadata_token = f"{http_method} {request_path} {content_length} {content_type}"
unsigned_authentication_token = f"{request_token} - {request_metadata_token}"

signature = hmac.new(
    api_secret_key.encode('utf-8'),
    unsigned_authentication_token.encode('utf-8'),
    hashlib.sha256
).digest()
request_signature = base64.b64encode(signature).decode('utf-8')

authentication_token = f"{request_token} {request_signature}"
print(authentication_token)

Let's say that timestamp and nonce in our case was:

timestamp20171123.231834.311
nonced374ad26-6f8e-4d72-9004-4c713409bacd

Then the above program prints out

oh91tDqJySK8wur2V6ZNhg 20171123.231834.311 d374ad26-6f8e-4d72-9004-4c713409bacd - cCalf3gwUOFaiLsTHWJSShGWem4cuyTFmFkquhzAbes=

And the complete signed request becomes:

GET /v3/igr/dub/foo/bar/receive?expire=5&recid=00001 HTTP/1.1  
host: api.instantcmr.com  
x-icmr-auth-1: oh91tDqJySK8wur2V6ZNhg 20171123.231834.311 d374ad26-6f8e-4d72-9004-4c713409bacd - cCalf3gwUOFaiLsTHWJSShGWem4cuyTFmFkquhzAbes=
© 2025 instantCMR LtdAPI Legal Disclaimer