Authentication

Authenticate with an API key + secret + passphrase

Authentication is performed after the WebSocket connection is established. It uses the same API keys as the REST API.

Request

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "authenticate",
  "params": {
    "key": "<api key>",
    "signature": "<base64 HMAC-SHA256>",
    "timestamp": 1747035005657,
    "passphrase": "<api passphrase>",
    "nonce": "<random 8-128 char string>"
  }
}
FieldDescription
keyAPI key (created in the API section of your account settings).
passphraseAPI passphrase set when creating the key.
timestampCurrent time in milliseconds. Must be within ±10 seconds of server time.
nonceRandom string between 8 and 128 characters. Must be unique per (timestamp, key).
signatureBase64 of HMAC-SHA256(apiSecret, "${timestamp}${nonce}").

Replay protection: a (apiKey, timestamp, nonce) tuple cannot be reused within 30 seconds.

Signing examples

JavaScript

import { createHmac, randomBytes } from 'node:crypto'

const timestamp = Date.now()
const nonce = randomBytes(16).toString('hex')
const signature = createHmac('sha256', apiSecret).update(`${timestamp}${nonce}`).digest('base64')

Python

import base64, hmac, hashlib, secrets, time

timestamp = int(time.time() * 1000)
nonce = secrets.token_hex(16)
signature = base64.b64encode(
  hmac.new(api_secret.encode(), f"{timestamp}{nonce}".encode(), hashlib.sha256).digest()
).decode()

Response

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "authenticated": true,
    "permissions": ["account:deposits:read", "futures:isolated:read"]
  }
}

Errors

error.data.codeCause
UNAUTHORIZEDInvalid signature, expired/future timestamp (>10s skew), or replayed nonce.
TOO_MANY_REQUESTSMore than 20 authenticate attempts from this IP in the last 60 seconds.
BAD_REQUESTMissing or malformed parameters.

TOO_MANY_REQUESTS includes structured data:

{
  "code": "TOO_MANY_REQUESTS",
  "data": { "limit": 20, "windowMs": 60000, "retryAfterMs": 12345, "scope": "authenticate" }
}

Re-authenticating with a different user automatically clears any private-topic subscriptions tied to the previous session.

On this page