Skip to main content

HMAC Authentication


Private API endpoints require authentication using HMAC SHA256 signatures generated with your API Secret.

The authentication ensures:

  • Request integrity
  • Request authenticity
  • Protection against replay attacks

Authentication Flow​

Every authenticated request follows this process:

  1. Generate a timestamp
  2. Build the payload string
  3. Generate HMAC SHA256 signature
  4. Base64 encode the signature
  5. Send request with required headers
  6. Server validates signature

Required Headers​

All private endpoints require these headers:

HeaderRequiredDescription
X-API-KeyYesYour cabinet generated API key
X-SignatureYesBase64 encoded HMAC SHA256 signature
X-TimestampYesRequest timestamp in milliseconds
X-Recv-WindowNoMaximum allowed request age in ms

Step 1 — Generate Timestamp​

Timestamp must be UNIX time in milliseconds.

Example:

1770990729000

Example (Javascript):

const timestamp = Date.now().toString()

Step 2 — Build Payload​

Payload format:

HTTP_METHOD + "\n" +
PATH + "\n" +
TIMESTAMP + "\n" +
RECV_WINDOW + "\n" +
BODY

Important rules:

  • Method must be uppercase
  • Path must include query parameters
  • New lines must be preserved
  • Body must match request exactly
  • Empty body must be empty string

Payload Examples​

GET example​

Request:

GET /open_api/api_profiles?exchanges=BINANCE,KRAKEN

Payload:

GET
/open_api/api_profiles?exchanges=BINANCE,KRAKEN
1770990729000
60000
Note

GET requests have empty body.

POST example​

Request:

POST /open_api/position

Body:

{
"key":"value",
"key1":"value1"
}

Payload:

POST
/open_api/position
1770990729000
60000
{"key":"value","key1":"value1"}
Important

Body must match serialized JSON exactly.

Step 3 — Generate Signature​

Signature formula:

Base64(HMAC_SHA256(Secret, Payload))

Step 4 — Add Headers​

Example headers:

X-API-Key: your_api_key
X-Signature: generated_signature
X-Timestamp: 1770990729000
X-Recv-Window: 60000

Implementation Examples​

// Pre-request Script
const apiKey = "your_api_key";
const apiSecret = "your_secret_key";
const timestamp = Date.now().toString();
const recvWindow = 60000;
const method = pm.request.method;

let path = "/" + pm.request.url.path.join("/");

if (pm.request.url.query.count() > 0) {
path += "?" + pm.request.url.query.map((q) => { return `${q.key}=${q.value}` }).join("&");
}

let body = "";

if (pm.request.body && pm.request.body.raw) {
body = pm.request.body.raw;
}

const payload =
method + "\n" +
path + "\n" +
timestamp + "\n" +
(recvWindow ?? '') + "\n" +
body;

const signature = CryptoJS.enc.Base64.stringify(
CryptoJS.HmacSHA256(payload, apiSecret)
);

pm.request.headers.upsert({
key: "X-API-Key",
value: apiKey
});

pm.request.headers.upsert({
key: "X-Timestamp",
value: timestamp
});

pm.request.headers.upsert({
key: "X-Signature",
value: signature
});

if (recvWindow) {
pm.request.headers.upsert({
key: "X-Recv-Window",
value: recvWindow
});
}

Server Validation Process​

Server validates:

  1. API key exists and not expired
  2. Signature matches
  3. Timestamp is valid
  4. Request is within receive window
  5. Payload integrity

Validation logic example:

abs(server_time - timestamp) <= recv_window

If X-Recv-Window is not provided:

Default window:

10000 ms

Security Requirements​

Security Rules

Never share your API Secret.

Never send API Secret in requests.

Always generate signature server-side.

Rotate keys if compromised.

Common Mistakes​

Most authentication failures are caused by:

ProblemCause
Invalid signatureWrong payload formatting
Invalid signatureMissing newline characters
Invalid signatureBody mismatch
Timestamp errorClient clock incorrect
Expired requestReceive window too small
Invalid signatureMethod not uppercase

Best Practices​

Recommended practices:

  • Sync time using NTP
  • Use 30–60 second receive window
  • Always stringify JSON consistently
  • Log payload during debugging
  • Never modify body after signing

Summary​

Authentication requires:

Signature = Base64(HMAC_SHA256(secret, payload))

Payload:

method + path + timestamp + recv_window + body

Headers:

X-API-Key
X-Signature
X-Timestamp
X-Recv-Window