> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hoplynk.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Kit WebSocket

> Stream live GPS and link telemetry for a kit over WebSocket.

## Endpoint

```
WSS https://argus.hoplynk.com/api/kits/{kit_id}/ws
```

## Query Parameters

| Parameter  | Type   | Default | Description                                                       |
| ---------- | ------ | ------- | ----------------------------------------------------------------- |
| `feeds`    | string | `gps`   | Comma-separated feeds to subscribe to. Options: `gps`, `starlink` |
| `interval` | float  | `1.0`   | Push interval in seconds. Range: `0.5`–`10.0`                     |

## Auth handshake

Send your API key as the first message after connecting. The server replies with `ready` before streaming data.

```
Client → Server:  { "type": "auth", "key": "hlk_..." }
Server → Client:  { "type": "ready", "feeds": ["gps", "starlink"] }
Server → Client:  { "type": "data", "feed": "gps", "payload": {...}, "ts": "..." }
```

<Info>
  The API key is sent in the message body, not the URL, so it is never logged by proxies or load balancers.
</Info>

## Data message schema

```json theme={null}
{
  "type": "data",
  "feed": "gps",
  "payload": {
    "latitude": 31.111125,
    "longitude": -93.273234,
    "altitude": 550.2,
    "source": "starlink",
    "stale": false
  },
  "ts": "2026-05-18T14:27:01.123Z"
}
```

## Error and close events

```json theme={null}
{ "type": "error", "message": "Invalid credentials" }
{ "type": "close", "code": 4001 }
```

The SDK auto-reconnects on disconnect unless you call `stream.close()`.

## Available feeds

| Feed       | Payload fields                                                                    |
| ---------- | --------------------------------------------------------------------------------- |
| `gps`      | `latitude`, `longitude`, `altitude`, `source`, `stale`, `kit_location`            |
| `starlink` | `latency_ms`, `download_mbps`, `upload_mbps`, `signal_quality`, `obstruction_pct` |

## Example

<CodeGroup>
  ```python Python theme={null}
  with client.kit_stream(kit_id, feeds=["gps", "starlink"]) as stream:
      for event in stream:
          feed = event["feed"]
          p = event["payload"]
          if feed == "gps":
              print(f"GPS: {p['latitude']}, {p['longitude']}  ({p.get('kit_location')})")
          elif feed == "starlink":
              print(f"Starlink: {p['latency_ms']}ms  ↓{p['download_mbps']} Mbps")
  ```

  ```javascript JavaScript theme={null}
  const stream = client.stream({ kitId, feeds: ['gps', 'starlink'] })

  stream.on('ready', ({ feeds }) => console.log('streaming', feeds))
  stream.on('data', ({ feed, payload, ts }) => {
    if (feed === 'gps') {
      console.log(payload.latitude, payload.longitude)
    }
  })

  // Clean up
  stream.close()
  ```

  ```javascript Raw WebSocket theme={null}
  const ws = new WebSocket('wss://argus.hoplynk.com/api/kits/YOUR_KIT_ID/ws?feeds=gps,starlink&interval=1')

  ws.onopen = () => ws.send(JSON.stringify({ type: 'auth', key: 'hlk_...' }))
  ws.onmessage = ({ data }) => {
    const msg = JSON.parse(data)
    if (msg.type === 'data') console.log(msg.feed, msg.payload)
  }
  ```
</CodeGroup>
