Documentation Index
Fetch the complete documentation index at: https://hypernode-docs.polynode.dev/llms.txt
Use this file to discover all available pages before exploring further.
WebSocket connections drop. Networks fail. Rate limits hit. This guide covers how to build a resilient client.
Reconnection
hypernode WebSocket connections can drop due to server restarts, network issues, or idle timeouts. Your client must handle reconnection.
Basic pattern
import WebSocket from "ws";
const API_KEY = "pn_live_YOUR_KEY";
const URL = `wss://hyper.polynode.dev/ws?key=${API_KEY}`;
let ws: WebSocket;
let reconnectDelay = 1000; // Start at 1 second
const MAX_DELAY = 30000; // Cap at 30 seconds
function connect() {
ws = new WebSocket(URL);
ws.on("open", () => {
console.log("Connected");
reconnectDelay = 1000; // Reset on successful connect
// Re-subscribe after every reconnect
ws.send(JSON.stringify({
action: "subscribe",
filters: { action_types: ["order", "fill"] }
}));
});
ws.on("message", (raw) => {
const event = JSON.parse(raw.toString());
handleEvent(event);
});
ws.on("close", (code, reason) => {
console.log(`Disconnected: ${code} ${reason}`);
scheduleReconnect();
});
ws.on("error", (err) => {
console.error("WebSocket error:", err.message);
// on("close") will fire after this
});
}
function scheduleReconnect() {
const jitter = Math.random() * 1000;
const delay = Math.min(reconnectDelay + jitter, MAX_DELAY);
console.log(`Reconnecting in ${Math.round(delay)}ms`);
setTimeout(() => {
reconnectDelay = Math.min(reconnectDelay * 2, MAX_DELAY);
connect();
}, delay);
}
connect();
Python
import json
import time
import websocket
API_KEY = "pn_live_YOUR_KEY"
URL = f"wss://hyper.polynode.dev/ws?key={API_KEY}"
def on_open(ws):
print("Connected")
ws.send(json.dumps({
"action": "subscribe",
"filters": {"action_types": ["order", "fill"]}
}))
def on_message(ws, message):
event = json.loads(message)
handle_event(event)
def on_close(ws, close_status_code, close_msg):
print(f"Disconnected: {close_status_code}")
def on_error(ws, error):
print(f"Error: {error}")
# websocket-client handles reconnection with run_forever
while True:
try:
ws = websocket.WebSocketApp(
URL,
on_open=on_open,
on_message=on_message,
on_close=on_close,
on_error=on_error,
)
ws.run_forever()
except Exception as e:
print(f"Connection failed: {e}")
time.sleep(5)
Key rules
Re-subscribe on every reconnect
Subscriptions are not persisted across connections. After reconnecting, you must send your subscribe messages again. Keep your subscription configs in a variable so you can replay them.
const MY_SUBSCRIPTIONS = [
{ action: "subscribe", filters: { assets: ["BTC"], action_types: ["order", "fill"] } },
{ action: "subscribe", filters: { addresses: ["0xabc..."] } },
];
ws.on("open", () => {
for (const sub of MY_SUBSCRIPTIONS) {
ws.send(JSON.stringify(sub));
}
});
No replay or gap-fill
hypernode does not replay missed events during a disconnection. If your connection drops for 5 seconds, events during that window are lost. Design your application to tolerate gaps.
If you need guaranteed delivery, combine the stream with periodic REST API polling:
// Stream for real-time updates
ws.on("message", handleEvent);
// Poll every 30 seconds as a safety net
setInterval(async () => {
const response = await fetch("https://hyper.polynode.dev/v2/user/open-orders?address=0x...", {
headers: { "x-api-key": API_KEY }
});
const orders = await response.json();
reconcileState(orders);
}, 30000);
Exponential backoff with jitter
Don’t reconnect immediately in a tight loop. Use exponential backoff (1s, 2s, 4s, 8s, …) with random jitter to avoid thundering herd problems.
Error responses
HTTP errors during handshake
| Status | Meaning | Action |
|---|
| 401 | Invalid or missing API key | Check your key |
| 403 | Key is disabled | Contact support |
| 429 | Connection limit reached | Close other connections or upgrade tier |
WebSocket errors after connection
Subscription errors are delivered as JSON messages:
{"error": "subscription limit reached for free tier (max 1)"}
Handle these in your message handler:
ws.on("message", (raw) => {
const msg = JSON.parse(raw.toString());
if (msg.error) {
console.error("Server error:", msg.error);
return;
}
handleEvent(msg);
});
Rate limits
- Connections per key: determined by your tier (1 for free, 5 for starter, up to 500 for enterprise)
- Subscriptions per connection: determined by your tier
- Messages: no rate limit on inbound subscribe/unsubscribe messages
- Events delivered: no throttling, you get everything matching your filters
Health checks
If you need to verify the service is up before connecting:
curl https://hyper.polynode.dev/health
Returns {"status":"ok"} when the stream service is running.
Browser clients
If running in a browser, handle tab visibility to avoid wasting resources:
document.addEventListener("visibilitychange", () => {
if (document.hidden) {
ws.close();
} else {
connect(); // Reconnect when tab becomes visible
}
});