Hydra
Docs

How to subscribe and unsubscribe from individual data streams.

Subscribing to Streams

After connecting, you must explicitly subscribe to the streams you want to receive. You will not receive any data until you subscribe.

Subscribe

Send a subscribe action with the list of stream IDs you want:

{
  "action": "subscribe",
  "streams": ["aircraft", "signals", "alerts"]
}

Response:

{
  "type": "subscribed",
  "ts": 1710000000000,
  "data": {
    "subscribed": ["aircraft", "signals", "alerts"],
    "rejected": [],
    "active": ["aircraft", "signals", "alerts"]
  }
}

If you request a stream outside your JWT scope it will appear in rejected:

{
  "type": "subscribed",
  "data": {
    "subscribed": ["signals", "alerts"],
    "rejected": ["aircraft"],
    "rejectedReason": { "aircraft": "Stream not in token scope" },
    "active": ["signals", "alerts"]
  }
}

Unsubscribe

Stop receiving a stream without disconnecting:

{
  "action": "unsubscribe",
  "streams": ["aircraft"]
}

Response:

{
  "type": "unsubscribed",
  "data": {
    "unsubscribed": ["aircraft"],
    "active": ["signals", "alerts"]
  }
}

List Active Subscriptions

{ "action": "list" }

Response:

{
  "type": "subscriptions",
  "data": {
    "active": ["signals", "alerts"],
    "available": ["aircraft", "signals", "alerts", "cyber"]
  }
}

Subscribing to All Available Streams

{
  "action": "subscribe",
  "streams": ["*"]
}

This subscribes you to every stream in your JWT scope.

Example — Subscribe and Process

const ws = new WebSocket(`wss://api.hydra.app/stream?token=${jwt}`)

ws.addEventListener('open', () => {
  // Subscribe after connection is established
  ws.send(JSON.stringify({
    action: 'subscribe',
    streams: ['signals', 'alerts', 'markets']
  }))
})

ws.addEventListener('message', (event) => {
  const msg = JSON.parse(event.data)

  if (msg.type === 'subscribed') {
    console.log('Now receiving:', msg.data.active)
    return
  }

  switch (msg.stream) {
    case 'signals':
      handleIntelSignal(msg.data)
      break
    case 'alerts':
      handleMissileAlert(msg.data)
      break
    case 'markets':
      handleMarketUpdate(msg.data)
      break
  }
})