Skip to main content

Authentication

TL;DR

Authentication has two layers. An account bearer token (POST /auth/token) gates access to the venue. A per-order Ed25519 trading-key signature proves cryptographic ownership of each order. You need the token to talk to the venue and the signature to place, cancel, or modify an order.

The credential model

Two layers, two questions.

LayerCredentialQuestion it answers
AccountBearer token"Is this caller allowed to use the venue?"
OrderTrading-key signature"Who cryptographically owns this order?"

The account layer is operational: it enables rate-limiting and audit, and is provisioned out of band (you receive an api_key, an api_secret, and a passphrase). The order layer is cryptographic: a trading key is an Ed25519 keypair you control, and the venue attributes, and ultimately settles, each order to the key that signed it.

One account can drive many trading keys. A market-maker fleet or a set of sub-portfolios shares one account login but signs with distinct trading keys. Because the trading key is the identity that authorizes settlement, holding the bearer token alone never lets a caller move or cancel another key's orders.

POST /auth/token

Exchange API credentials for a short-lived bearer token.

POST /auth/token

Request

{
"api_key": "your-api-key",
"api_secret": "your-api-secret",
"passphrase": "your-passphrase"
}
FieldTypeRequiredDescription
api_keystringYesPublic credential identifier provisioned at account setup.
api_secretstringYesThe secret paired with api_key.
passphrasestringYesAccount-level passphrase (third factor).

Response

{
"access_token": "eyJhbGciOi...",
"token_type": "Bearer",
"expires_in": 3600,
"account_id": "acct_01H..."
}
FieldTypeDescription
access_tokenstringThe bearer token. Pass as Authorization: Bearer <token>.
token_typestringAlways Bearer.
expires_inintegerToken lifetime in seconds from issue.
account_idstringStable per-account identifier.

cURL

curl -s -X POST "$GATEWAY/auth/token" \
-H "Content-Type: application/json" \
-d '{
"api_key": "your-api-key",
"api_secret": "your-api-secret",
"passphrase": "your-passphrase"
}'

Using the bearer token

Send it on every authenticated REST request:

curl -s "$GATEWAY/orders/$ORDER_ID" \
-H "Authorization: Bearer $TOKEN"

On the WebSocket routes, pass it as a query parameter (the upgrade cannot carry a header from a browser); the Authorization header is also accepted:

wss://<gateway-host>/ws/orders?token=<access_token>

Token expiry and revocation

Tokens are short-lived (the expires_in window). Cache the token in-process and refresh it before expiry; a request with an expired token returns 401.

To invalidate a token before it expires:

POST /auth/token/revoke

with the token in the Authorization header. The token is denylisted immediately; subsequent requests with it return 401.

The order signature

Placing, cancelling, or modifying an order requires an Ed25519 signature from the order's trading key, in addition to the bearer token.

  • Place. Sign the canonical order body. The signature binds every economic field of the order (symbol, side, type, amount, price limit, expiry, the collateral-note commitment, the continuation anchor-pool hash, and a nonce) so the venue can attribute the order to your key without any per-order on-chain transaction.
  • Cancel. Sign a canonical cancel body over the order id, your trading key, and a cancel nonce.
  • Modify. Sign a cancel of the old order and a full new order; both signatures must come from the same trading key.

The canonical encodings are fixed-length and unambiguous, so re-encoding from JSON always yields the same bytes to sign. The SDK constructs and signs these for you. The exact field layout for each is on the corresponding endpoint page: Place Order, Cancel Order, Modify Order.

Public (unauthenticated) endpoints

These require no token:

  • GET /health, GET /system/status, GET /time
  • GET /info, GET /attestation, the /evidences/* files
  • GET /instruments, GET /instruments/{symbol}
  • GET /tree/root
  • GET /transparency

Everything else requires the bearer token: order management, account-scoped reads (/tree/inclusion, /tree/leaves, /settlement/status), and the WebSocket streams.