The envelope and structure of all WebSocket messages.
Message Format
All messages on the Hydra WebSocket — both server-to-client stream data and client-to-server commands — follow a consistent structure.
Server → Client Envelope
interface HydraMessage {
stream?: string // stream ID ('aircraft', 'signals', etc.) — absent on control messages
type: string // message type within the stream
ts: number // Unix millisecond timestamp (server time)
data: unknown // payload — type depends on stream + type combo
}
Stream Data Message
{
"stream": "signals",
"type": "signal_new",
"ts": 1710000000000,
"data": {
"id": "clxxx",
"title": "...",
"severity": 4,
...
}
}
Control Message (no stream field)
{
"type": "heartbeat",
"ts": 1710000000000,
"data": null
}
Client → Server Commands
interface HydraCommand {
action: 'subscribe' | 'unsubscribe' | 'list' | 'ping'
streams?: string[] // required for subscribe/unsubscribe
}
All Server Message Types
stream |
type |
Description |
|---|---|---|
| — | connected |
Initial connection confirmation |
| — | subscribed |
Subscription confirmation |
| — | unsubscribed |
Unsubscription confirmation |
| — | subscriptions |
Response to list command |
| — | heartbeat |
Keep-alive ping (every 30s) |
| — | error |
Error from a command |
aircraft |
position_update |
Aircraft position refresh |
aircraft |
pattern_detected |
Movement pattern identified |
vessels |
position_update |
Vessel position refresh |
vessels |
status_change |
Navigational status change |
alerts |
alert_issued |
New missile/rocket alert |
alerts |
alert_cleared |
Alert cancelled or expired |
cyber |
threat_pulse |
New cyber threat campaign |
airspace |
restriction_active |
New airspace restriction |
airspace |
restriction_expired |
Restriction has expired |
signals |
signal_new |
New intelligence signal |
markets |
market_update |
Market data refresh |
markets |
price_spike |
Significant price movement |
social |
osint_signal |
High-relevance social post |
earthquakes |
seismic_event |
Seismic event detected |
Error Messages
When a command fails, the server sends an error:
{
"type": "error",
"ts": 1710000000000,
"data": {
"code": "STREAM_NOT_IN_SCOPE",
"message": "Stream 'aircraft' is not in your token scope",
"action": "subscribe"
}
}
| Code | Meaning |
|---|---|
STREAM_NOT_IN_SCOPE |
Requested stream not in your JWT |
INVALID_ACTION |
Unknown action sent |
RATE_LIMITED |
Too many messages sent |
TOKEN_EXPIRED |
JWT has expired — reconnect with new token |
TypeScript Types
// Install: npm install hydra-stream-types
import type {
AircraftPositionUpdate,
AircraftPatternDetected,
VesselPositionUpdate,
AlertIssued,
AlertCleared,
CyberThreatPulse,
AirspaceRestrictionActive,
IntelSignalNew,
MarketUpdate,
MarketPriceSpike,
SocialOsintSignal,
SeismicEvent,
} from 'hydra-stream-types'
Note
The hydra-stream-types npm package ships TypeScript definitions for every message type. It is kept in sync with the API automatically.