Introduction#
The Pinax WebSocket service fans out Substreams blocks to many subscribers from a single ingestion path. Every message is JSON; payloads carry decoded DatabaseChanges rows grouped by (network, table). Reorgs are surfaced as explicit undo events.
module_hash in production and watch for stream lifecycle fatal messages.Endpoint#
Stream selectors take the form <network>@<table>. Wildcards are accepted on either side.
| URL | Mode | Envelope |
|---|---|---|
/ws/<a> | Single channel | Raw payload |
/ws/<a>/<b>/… | Multi channel | Wrapped |
/stream?streams=<a>/<b>/… | Combined, query string | Wrapped |
When wrapped, every payload is delivered as { "stream": "<id>", "data": <raw> }. Bare /ws with no streams returns HTTP 400 — use /ws/*@* to explicitly opt into every stream.
Authentication#
Authenticate every connection with your project JWT, passed as a ?token= query parameter on the upgrade URL. Browsers can't set headers on a WebSocket upgrade, so the token rides on the URL for every client — browser, Node, Go, anything.
wss://ws.pinax.network/ws/<network@table>?token=<JWT>
Grab the JWT from your project's API keys page. Treat it like a password — anyone holding it can open a stream against your quota. Rotate via the dashboard if it leaks.