Skip to main content

Private Streams

Real-time streams of your own orders and fills. Two subjects:

SubjectPurpose
v1.f.ex1.private.subAccountId.<id>.orderOrder state changes — New, PartiallyFilled, Filled, Cancelled.
v1.f.ex1.private.subAccountId.<id>.tradeExecution (fill) events — one per match.

<id> is your sub-account ID. You'll receive it as sub_account_id on every payload, and it's also visible in the response of Place Order (via the order context).

Authentication

Private subjects can only be subscribed to with a valid signature. The flow:

  1. Call GET /dma/api/v1/socket/signature as a normal authenticated HFT request.
  2. The response contains {api_key, expires, signature} — these are credentials specifically for the HFT WebSocket auth message, separate from your CoinSwitch REST API key.
  3. Use those three values to authenticate the NATS WebSocket connection.

Get a signature

MethodGET
Path/dma/api/v1/socket/signature

Query parameters

ParameterTypeRequiredDescription
expires_in_secondsintegerNoLifetime of the returned signature, in seconds. Default 300. The returned expires field is now + expires_in_seconds, expressed as a Unix-ms timestamp.

Request

from reference_client import sign_request, BASE_URL
import requests

headers, path = sign_request("GET", "/dma/api/v1/socket/signature")
r = requests.get(BASE_URL + path, headers=headers)
creds = r.json()
# {"api_key": "...", "expires": 1756461000000, "signature": "..."}

Response

{
"api_key": "<api key for the websocket auth message>",
"expires": 1756461000000,
"signature": "<signature hex>"
}
FieldTypeDescription
api_keystringThe API key to use on the WebSocket auth payload.
expiresintegerExpiry timestamp (Unix ms). After this, the signature is rejected.
signaturestringThe signature to use on the WebSocket auth payload. Computed on our side; you don't compute this yourself — just pass it through.
caution

Don't compute this signature client-side. Always call /dma/api/v1/socket/signature to obtain it.

Authenticate the WebSocket

Once connected to the NATS WebSocket, send the auth message below before subscribing to any private subject:

{
"op": "auth",
"args": ["<api_key>", <expires>, "<signature>"]
}

Use the values from the /dma/api/v1/socket/signature response. Subscribe to your private subjects only after the auth message is acknowledged.

If expires is in the past (or close to it), the auth is rejected — request a fresh signature with a longer expires_in_seconds if needed.

Order Updates

Subject: v1.f.ex1.private.subAccountId.<id>.order

{
"t": 1756478182146,
"e": "COINSWITCHX",
"event_type": "order.linear",
"E": 1756478182146,
"T": 0,
"user_id": "491363048",
"sub_account_id": "491363048",
"o": {
"category": "linear",
"symbol": "SOLUSDT",
"orderId": "68a4579e-c396-4427-b055-7a8bcafbd48d",
"orderLinkId": "7b708608-7e1d-456b-aa78-43a9892c2fda",
"side": "Buy",
"positionIdx": 0,
"orderStatus": "Filled",
"cancelType": "UNKNOWN",
"rejectReason": "EC_NoError",
"timeInForce": "IOC",
"price": "220.25",
"qty": "0.2",
"avgPrice": "209.76",
"leavesQty": "0",
"leavesValue": "0",
"cumExecQty": "0.2",
"cumExecValue": "41.952",
"cumExecFee": "0.0146832",
"orderType": "Market",
"lastPriceOnCreated": "209.75",
"closeOnTrigger": false,
"reduceOnly": false,
"createType": "CreateByUser",
"updatedTime": "1756478182110"
}
}

You'll receive one of these every time the order's orderStatus changes (placed → filled, cancelled, rejected, etc.). The o object mirrors the shape of result.list[] on Get Orders (Realtime).

Trade Updates

Subject: v1.f.ex1.private.subAccountId.<id>.trade

{
"t": 1756478116649,
"e": "COINSWITCHX",
"event_type": "execution.linear",
"E": 1756478116649,
"T": 1756478116611,
"user_id": "491363048",
"sub_account_id": "491363048",
"o": [
{
"category": "linear",
"symbol": "BTCUSDT",
"orderId": "316ea49e-59b3-42c5-9d71-edaf2504b0f8",
"orderLinkId": "cf8cc52d-b749-4d97-aeb9-f44c90b94092",
"side": "Sell",
"orderPrice": "107396.1",
"orderQty": "0.002",
"leavesQty": "0",
"createType": "CreateByUser",
"orderType": "Market",
"execFee": "0.07593348",
"execId": "a1076552-0c0f-5a56-a064-5a653f9172c6",
"execPrice": "108476.4",
"execQty": "0.002",
"execType": "Trade",
"execValue": "216.9528",
"execTime": "1756478116611",
"isMaker": false,
"feeRate": "0.00035",
"closedSize": "0.002",
"seq": 448368491576
}
]
}

o is an array — a single matching event can produce multiple executions (e.g. a market order eating through several resting orders). Each entry mirrors result.list[] on Execution List.

Each execution has a unique execId — use it as the primary key when you store fills locally, so retries or duplicate messages don't insert the same fill twice.