Skip to main content
A WebSocket connection takes your API key as a query parameter, because browsers can’t set a custom header on the handshake. That’s fine for a script running on your own machine. It’s not fine for a public web page, since anyone who opens the browser’s network tab can read the key straight out of the connection URL. The fix is the same one you’d already use for a REST key: never send it to the browser. Your backend holds the key, connects to NGN Market, and relays what it receives to your own users over a WebSocket connection that needs no key at all. This guide uses /v1/ws/prices, but the same pattern works for all six.

How it works

  1. Your backend opens one WebSocket connection to NGN Market, using the real API key from an environment variable.
  2. Your backend also runs its own WebSocket server, one your frontend connects to instead. No key required, since your backend is already authenticated upstream.
  3. Every message your backend receives from NGN Market gets forwarded to every browser client connected to it.
One upstream connection, however many browser tabs are watching it. That also means your app’s WebSocket connection usage doesn’t grow with your number of users. Only your backend’s one connection counts against your plan’s limit. See Limits.

Backend: connect upstream, serve downstream

Node.js

Browser: connect to your own server, not NGN Market

Browser
The message shape reaching the browser is identical to what your backend gets from NGN Market. You’re relaying it, not transforming it, so the rest of your frontend code (parsing snapshot/update, rendering prices) works exactly as it would if it had connected directly.

Tips

  • Reconnect the upstream connection, not just the browser side. If your backend’s connection to NGN Market drops, every browser client downstream goes quiet too, even though their own connections are still open. Add reconnect-with-backoff logic to the upstream.on('close', ...) handler above.
  • One upstream connection per symbol set you need, not per user. If different users need different watchlists on /v1/ws/prices, open one upstream connection per distinct symbol set your app actually needs, and fan each one out to the browser clients that asked for it. That’s still far fewer connections than one per user.
  • This is a normal pattern, not a workaround. Proxying a key-authenticated connection through your own server is exactly how you’d already handle a REST API key in a frontend app. WebSocket doesn’t change that rule, it just changes where the key would otherwise leak if you skipped this step.

WebSocket Authentication

Why the key travels as a query parameter

Limits

How connections are counted per account