English
HMAC Authentication
Every protected request requires four headers.
http
X-API-KEY: {api_key}
X-TIMESTAMP: {unix_epoch_milliseconds}
X-NONCE: {uuid-v4}
X-SIGNATURE: {base64_hmac_sha256}Build the string to sign with two newline characters between each field:
text
{HTTP_METHOD}\n\n{PATH_WITH_QUERY}\n\n{TIMESTAMP}\n\n{NONCE}\n\n{BODY_JSON}Use the uppercase method and the exact path and query string sent over HTTP. For GET and DELETE requests, the body component is empty. For POST requests, sign the exact serialized JSON bytes you send; changes in whitespace or key order change the signature.
Create a new timestamp, nonce, and signature for every attempt, including retries. Reusing a nonce can return NONCE_REPLAYED; excessive clock difference can return INVALID_TIMESTAMP.
See HMAC Request Signing for implementation examples and troubleshooting.
Canonicalization checklist
- Include the query string exactly as transmitted, including ordering and percent encoding.
- Use the same timestamp text in the header and canonical string.
- Serialize a POST body once, then sign and send that exact string.
- Do not add a newline before or after the five canonical fields.
- Preserve the
\n\nseparator after the nonce even when the body is empty. - Use the actual HMAC signing key, not a display token or masked secret.
Verification strategy
Unit-test signing with fixed inputs and a known expected Base64 signature. Add an integration test that calls /time, signs one GET request, and signs one POST request containing JSON. When debugging, compare hashes or redacted field lengths rather than logging the secret or full canonical request.
Authentication errors should not trigger a generic retry loop. Apply the returned action: synchronize time, generate a new nonce, replace the key, or regenerate the signature.