Authentication

Endpoint security type

API requests are likely to be tampered during transmission through the internet. To ensure that the request remains unchanged, all private interfaces other than public interfaces (basic information, market data) must be verified by signature authentication via API-KEY to make sure the parameters or configurations are unchanged during transmission.

Each created API-KEY need to be assigned with appropriate permissions in order to access the corresponding interface. Before using the interface, users is required to check the permission type for each interface and confirm there is appropriate permissions.

Authentication TypeDescription
NONEEndpoints are freely accessible
TRADEEndpoints requires sending a valid API-KEY and signature
USER_DATAEndpoints requires sending a valid API-KEY and signature
USER_STREAMThe endpoints requires sending a valid API-KEY
MARKET_DATAThe endpoints requires sending a valid API-KEY

Signature Authentication


Signature (TRADE & USER_DATA)

  • The SIGNED (signature required) endpoint needs to send a parameter, signature, in the query string or request body.

  • The endpoint is signed with HMAC SHA256. The HMAC SHA256 signature is the result of HMAC SHA256 encryption of the key. Use your secretKey as the key and totalParams as the value to complete this encryption process.

  • Signature is not case sensitive.

  • totalParams refers to concatenation of the query string and the request body.

All HTTP requests to API endpoints require authentication and authorization. The following headers should be added to all HTTP requests:

KeyValueTypeDescription
X-HK-APIKEYAPI-KEYstringThe API Access Key you applied for

Time-base security requirement

  • For a SIGNED endpoint, an additional parameter "timestamp" needs to be included in the request. This timestamp is in milliseconds and reflect the time when the request was intitated
  • An optional parameter (not mandatory) recvWindow can be used to specify the validity period of the request in milliseconds. If recvWindow is not sent as part of the request, the default value is 5000

📘

If your timestamp is ahead of serverTime it needs to be within 1 second + serverTime

The logic of this parameter is as follows:

 if (timestamp < (serverTime + 1000) && (serverTime - timestamp) <= recvWindow) {
    // process request
  } else {
    // reject request
  }
  • Trading and timeliness are closely interconnected. Network can sometimes be unstable or unreliable, which can lead to inconsistent times when requests are sent to the server.
  • With recvWindow, you can specify how many milliseconds the request is valid, otherwise it will be rejected by the server.

📘

A relatively small recvWindow (5000 or less) is recommended!

Example 1: In queryString

  • queryString: symbol=ETHBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=0.1&recvWindow=5000&timestamp=1538323200000
  • HMAC SHA256 signature:
echo -n "symbol=ETHBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=0.1&recvWindow=5000&timestamp=1538323200000" | openssl dgst -sha256 -hmac "lH3ELTNiFxCQTmi9pPcWWikhsjO04Yoqw3euoHUuOLC3GYBW64ZqzQsiOEHXQS76"

Shell standard output: 5f2750ad7589d1d40757a55342e621a44037dad23b5128cc70e18ec1d1c3f4c6

  • curl command:
curl -H "X-HK-APIKEY: tAQfOrPIZAhym0qHISRt8EFvxPemdBm5j5WMlkm3Ke9aFp0EGWC2CGM8GHV4kCYW" -X POST 'https://$HOST/api/v1/spot/order?symbol=ETHBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=0.1&recvWindow=5000&timestamp=1538323200000&signature=5f2750ad7589d1d40757a55342e621a44037dad23b5128cc70e18ec1d1c3f4c6'

Example 2: In the request body

  • requestBody: symbol=ETHBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=0.1&recvWindow=5000&timestamp=1538323200000
  • HMAC SHA256 signature:
echo -n "symbol=ETHBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=0.1&recvWindow=5000&timestamp=1538323200000" | openssl dgst -sha256 -hmac "lH3ELTNiFxCQTmi9pPcWWikhsjO04Yoqw3euoHUuOLC3GYBW64ZqzQsiOEHXQS76"

Shell standard output: 5f2750ad7589d1d40757a55342e621a44037dad23b5128cc70e18ec1d1c3f4c6

  • curl command:
curl -H "X-HK-APIKEY: tAQfOrPIZAhym0qHISRt8EFvxPemdBm5j5WMlkm3Ke9aFp0EGWC2CGM8GHV4kCYW" -X POST 'https://$HOST/api/v1/spot/order' -d 'symbol=ETHBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=0.1&recvWindow=5000&timestamp=1538323200000&signature=5f2750ad7589d1d40757a55342e621a44037dad23b5128cc70e18ec1d1c3f4c6'

Example 3: mixing queryString and request body

  • queryString:
    symbol=ETHBTC&side=BUY&type=LIMIT&timeInForce=GTC
  • requestBody:
    quantity=1&price=0.1&recvWindow=5000×tamp=1538323200000
  • HMAC SHA256 signature:
echo -n "symbol=ETHBTC&side=BUY&type=LIMIT&timeInForce=GTCquantity=1&price=0.1&recvWindow=5000&timestamp=1538323200000" | openssl dgst -sha256 -hmac "lH3ELTNiFxCQTmi9pPcWWikhsjO04Yoqw3euoHUuOLC3GYBW64ZqzQsiOEHXQS76"

Shell standard output: 885c9e3dd89ccd13408b25e6d54c2330703759d7494bea6dd5a3d1fd16ba3afa

  • curl command:
curl -H "X-HK-APIKEY: tAQfOrPIZAhym0qHISRt8EFvxPemdBm5j5WMlkm3Ke9aFp0EGWC2CGM8GHV4kCYW" -X POST 'https://$HOST/openapi/v1/order?symbol=ETHBTC&side=BUY&type=LIMIT&timeInForce=GTC' -d 'quantity=1&price=0.1&recvWindow=5000&timestamp=1538323200000&signature=885c9e3dd89ccd13408b25e6d54c2330703759d7494bea6dd5a3d1fd16ba3afa'

Note the difference in Example 3, where there is no & between "GTC" and "quantity = 1".