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
ping messageThe ping is an authenticated message like any other: it carries your credentials and a freshly computed signature. See Authentication.
| Field | Type | Required | Description |
|---|---|---|---|
messageType | string | ✅ | ping |
key | string | ✅ | Your API public key |
passphrase | string | ✅ | Your API passphrase |
timestamp | string | ✅ | Unix epoch seconds (the same value used to compute the signature) |
signature | string | ✅ | Base64-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
pingneeds a freshtimestampand asignaturerecomputed for that timestamp — you cannot reuse a previous signature. - One heartbeat per connection. A single
pingkeeps 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):
- Reconnect to the WebSocket endpoint, using a backoff strategy (e.g. exponential backoff with jitter) to avoid hammering the server.
- Re-authenticate and resubscribe. Replay your
subscribemessage(s) — the balances subscription and each price symbol — with a freshtimestampandsignature. - Restart the heartbeat timer on the new connection.
- Re-baseline your state. On the balances feed, the server sends a fresh
initial-balancesnapshot 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 nextprice-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
| Environment | WebSocket URL |
|---|---|
| Production | wss://ws.zerohash.com |
| Certification (testing) | wss://ws.cert.zerohash.com |
Next steps
- Authentication — signing every message, including pings
- Balance Subscription — resubscribing the balances feed
- Price Subscription — resubscribing the prices feed