Skip to content
Last updated

Errors

Before upgrade, authentication and connection/admission errors are HTTP responses. After upgrade, application errors arrive as error envelopes. A transport failure or a forced close can occur without a final application error message.

Before the Upgrade

HTTP statusMeaning
401Missing or invalid API key
429Rate limit or per-API-key connection limit reached
503Server connection capacity unavailable

X-WS-Error carries a short description. A simultaneous connection race can reject a socket just after upgrade with PolicyViolation, without an error envelope; wait and check existing connections before retrying. Do not assume every policy close has the same cause.

Validation and Correlation

An account request can report several field errors together:

{
  "msg_type": "error",
  "id": "msg_675d3f4bbc7e4f27aadd0db8444f",
  "request_id": "bad-account-sub",
  "timestamp": "2026-10-26T15:00:00Z",
  "v": 4,
  "payload": {
    "errors": [
      {
        "code": "MANDATORY_PARAM_EMPTY_OR_MALFORMED",
        "field": "payload.account",
        "message": "Missing parameter"
      },
      {
        "code": "INVALID_PARAMETER",
        "field": "payload.broker_id",
        "message": "Invalid parameter"
      }
    ]
  }
}

A single error uses payload.code, optional field and message. Multiple errors use the payload.errors array. Echoed request_id associates a rejection with its request even while other data and heartbeats are arriving.

Account validationResult
Missing/blank payload.accountMANDATORY_PARAM_EMPTY_OR_MALFORMED
Account longer than 45 charactersINVALID_PARAMETER
Missing, zero or negative payload.broker_idINVALID_PARAMETER
Explicit zero or negative payload.person_idINVALID_PARAMETER
Any account payload.resume_fromINVALID_PARAMETER because account replay is unsupported
Unknown action/channel, malformed envelope or timestamp outside one minute of UTCValidation error on the affected field

Omitted person_id uses the authenticated session person; an explicit value does not grant access to someone else's account. Authorization checks the selected exact account/broker owner and current channel permissions/site authority.

Subscription Errors

CodeMeaning and action
FORBIDDENAccount/strategy authority denied. Correct access before retrying
ALREADY_EXISTSThe channel and physical identity are already subscribed or pending. A different person override does not create a second account subscription
NOT_FOUNDUnsubscribe requested an identity not currently subscribed
TOO_MANY_SUBSCRIPTIONSThe relevant account or strategy limit was reached. Unsubscribe unused identities first
SERVICE_UNAVAILABLEThe initial account snapshot or server connection capacity is unavailable. Retry the subscription with backoff
TOO_MANY_REQUESTSRequest rate exceeded. After upgrade, delay and retry the request while keeping the healthy connection
FRAGMENTUnsupported WebSocket fragmentation or invalid JSON
UNKNOWNUnexpected server error. Retain diagnostic IDs and contact API support

An unsubscribe acknowledgement follows a successful explicit unsubscribe. A pending account subscription can fail before its acknowledgement if the initial snapshot is unavailable. A missing update does not clear existing orders or positions.

Access Revocation

Changes to API-key or account access can close the connection. If an active account subscription is no longer authorized, the server removes it and sends an unsolicited subscription.ack with action: "unsubscribe", its channel, account, broker ID and person ID. It has no request_id. Stop using that channel's cached state; do not automatically resubscribe in a tight loop. A denial before activation returns a correlated FORBIDDEN error instead.

Other subscriptions can remain active when one channel is removed. Correlate requested acknowledgements by request_id and handle unsolicited ones separately.

Heartbeat, Slow Consumers and Transport Failures

A missed application heartbeat can close with NormalClosure and reason Ping timeout. Slow consumption can produce that same reason, so it does not uniquely identify the cause. Do not infer an exact close deadline from the close code or reason.

The server can close a slow connection with reason Outbound queue full. Reconnect and resubscribe. Transport failures or server shutdown can end a connection without an application error. A normal close code can still require recovery.

Process incoming messages promptly, acknowledge JSON heartbeats, and move blocking REST, storage or computation work outside the receive loop. Protocol Ping/Pong does not replace heartbeat.ack.

Reconnection Guidance

SituationAction
Invalid fields or FORBIDDENCorrect the cause; keep other healthy subscriptions running
Duplicate subscriptionUse the existing subscription or unsubscribe it before replacing it
Snapshot SERVICE_UNAVAILABLERetry that subscription with backoff; connection may remain usable
Rate limit after upgradeDelay the request. Reconnecting is unnecessary
Transport close or evictionReconnect with exponential backoff and jitter, then use the channel-specific rule below
Authority revokedMark affected state unavailable and obtain corrected authority before resubscribing

For strategy.signal and strategy.live_fills, retain separate successfully processed cursors and request bounded replay. For strategy.positions, resubscribe and replace the full collection. For every account.* channel, resubscribe without resume_from and replace state from the new initial snapshot. Clear stale account state rather than merging the old socket's baseline. See Recovery and Gap Fill.