Skip to main content

Authentication

All customer-facing /v1/* endpoints authenticate with a bearer token:

Authorization: Bearer <prefix>.<suffix>

Two flows produce bearer tokens, and the venue treats them uniformly:

  • API keys — minted via POST /v1/credentials, intended for programmatic trading.
  • Sessions — produced by POST /v1/auth/login (email + password), used by the terminal. Sessions are credential rows with a 7-day expiry; POST /v1/auth/logout revokes the presented one.

Public market data (instruments, books, trades, candles) and the WebSocket upgrade itself require no auth.

Token format

The token's prefix is the credential's public ID, used for lookup; the suffix is a high-entropy secret. The venue stores only a SHA-256 of the suffix.

The venue returns a bearer token exactly once, at creation:

  • POST /v1/auth/signup → session token, plus the account
  • POST /v1/credentialsdata.plaintext_key

GET /v1/credentials never returns secrets. If you lose a key, mint a new credential and DELETE the old one.

Entitlements

Each credential carries an entitlement bitmask. The default for an account's initial credential is 15 (all four bits):

BitValueEntitlementGrants
01TradeEnabledPlace and cancel orders
12WithdrawEnabledInitiate withdrawals
24DepositEnabledAllocate deposit addresses
38APITradingProgrammatic (vs UI-only) trading

Account states

Independently of credentials, every account has a lifecycle state. Endpoints check both the credential's entitlements and the account state:

Account statePlace orderCancel orderWithdraw
pending
active
trade_frozen
withdraw_frozen
fully_frozen
closed

Cancellation stays allowed in frozen states so you can manage positions down; a closed account is inert.

State-related rejections use the account_not_active and account_trade_frozen error codes.

WebSocket auth

Private channels (fill, account) unlock by presenting the same bearer on the upgrade request to GET /v1/ws. Public channels need no auth. Tokens never appear in URLs. See the streaming overview.