Skip to main content
This guide shows how to obtain a JWT and use it for authenticated REST and WebSocket access.

1) Obtain a JWT

Request a token from the authorization endpoint:
POST /api/v1/authorize
Content-Type: application/json
Example body:
{
  "public_key": "<Canton Party ID>",
  "signature": "",
  "timestamp_ms": 1731541800000,
  "nonce": "random-unique-string"
}
  • public_key: Canton Party ID associated with the user
  • timestamp_ms: Unix time in milliseconds
  • nonce: Unique value generated for the authorization request
Successful response:
{ "token": "<jwt>", "user_id": "<user_id>" }
Token validity: 7 days from issuance.

2) API Key Auth

Gateway supports API-key auth headers for programmatic access without obtaining a JWT first. Headers:
  • X-API-KEY: Your API public key
  • X-SIGNATURE: Ed25519 signature over EKIDEN_API|{method}|{uri}|{timestamp_ms}|{nonce}
  • X-TIMESTAMP-MS: Unix milliseconds
  • X-NONCE: Random unique string

3) Use the token for REST

Include the token as a Bearer in the Authorization header:
GET /api/v1/user/portfolio
Authorization: Bearer <jwt>
Private endpoints under /api/v1/user/* and certain actions require this header.

4) Use the token for private WebSocket

Connect to the private WS endpoint and authenticate, then subscribe to private topics:
  1. Connect: wss://api.cnt.ekiden.fi/ws/private
  2. Authenticate:
Client → Server
{ "op": "auth", "bearer": "<jwt>", "req_id": "auth-1" }
Server → Client
{ "op": "auth", "success": true, "user_id": "<user_id>", "req_id": "auth-1" }
  1. Subscribe to private topics (examples):
{ "op": "subscribe", "args": ["order", "position", "execution", "account_balance"], "req_id": "sub-1" }
Public topics like orderbook.1.BTCUSDC, trade.BTCUSDC, ticker.BTCUSDC are available on /ws/public without auth.

Timestamp units and replay protection

  • timestamp_ms is required in the authorize request and must be close to server time.
  • Each (public_key, nonce) pair may be used once; reusing a nonce will be rejected.

Optional: curl examples

Request token:
curl -X POST "https://api.cnt.ekiden.fi/api/v1/authorize" \
    -H "Content-Type: application/json" \
    -d '{
        "public_key": "<Canton Party ID>",
        "signature": "",
        "timestamp_ms": 1731541800000,
        "nonce": "b7d1c2e8f5a94f3db2f8c6a9d1e4"
    }'
Call a private REST endpoint:
curl -H "Authorization: Bearer <jwt>" \
    "https://api.cnt.ekiden.fi/api/v1/user/portfolio"

Troubleshooting

  • 400 on /authorize: check the request payload, timestamp_ms freshness, and nonce validity.
  • 401 on private REST or WS auth: token expired or invalid.
  • WS: authenticate before subscribing to private topics on /ws/private.