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