Maintaining Subscription

Once you've subscribed to the balances or prices feed, you must keep the connection alive with a heartbeat. A ping message must be sent every 20 seconds — if the server does not receive one in time, it closes the connection.

The ping message

The ping is an authenticated message like any other: it carries your credentials and a freshly computed signature. See Authentication.

FieldTypeRequiredDescription
messageTypestringping
keystringYour API public key
passphrasestringYour API passphrase
timestampstringUnix epoch seconds (the same value used to compute the signature)
signaturestringBase64-encoded HMAC-SHA256 signature

Example:

{
  "messageType": "ping",
  "key": "API_PUBLIC_KEY",
  "passphrase": "PASSPHRASE",
  "timestamp": "TIMESTAMP",
  "signature": "SIGNATURE"
}

Heartbeat guidance

  • Send within the 20-second window. Use a slightly shorter interval (e.g. every 15 seconds) to leave headroom for network latency and scheduling jitter.
  • Sign every ping. Each ping needs a fresh timestamp and a signature recomputed for that timestamp — you cannot reuse a previous signature.
  • One heartbeat per connection. A single ping keeps the whole connection alive, covering every subscription (all balance and price subscriptions) multiplexed over it.
  • Don't block the heartbeat. Run the ping on its own timer so heavy inbound message processing can't delay it past the 20-second limit.

Reconnection & Re-subscription

Long-lived TCP connections may experience network instability, timeouts, or ISP-related issues at any time. It is fundamental to have a reconnection / resubscription mechanism in place. When the connection drops (a socket close/error, or a missed heartbeat):

  1. Reconnect to the WebSocket endpoint, using a backoff strategy (e.g. exponential backoff with jitter) to avoid hammering the server.
  2. Re-authenticate and resubscribe. Replay your subscribe message(s) — the balances subscription and each price symbol — with a fresh timestamp and signature.
  3. Restart the heartbeat timer on the new connection.
  4. Re-baseline your state. On the balances feed, the server sends a fresh initial-balance snapshot on resubscribe — treat it as the source of truth, since you may have missed updates while disconnected. On the prices feed, resubscribe to each symbol and rebuild from the next price-update.
💡

Treat any unexpected disconnect as a signal to re-baseline, not just reconnect. Applying stale local state after a gap is a common source of drift.

Endpoints

EnvironmentWebSocket URL
Productionwss://ws.zerohash.com
Certification (testing)wss://ws.cert.zerohash.com

Next steps