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

# WebSocket

> Stream task events to your code over a persistent connection

Connect to the WebSocket to receive events from every task whose destination is **WebSocket**, plus [Twitter Global keyword](https://docs.tweet-catcher.com/plans.md#twitter-global) events

```text theme={null}
wss://monitor-api.tweet-catcher.com/websocket
```

> [!NOTE]
>
> Authenticate with your [API key](https://docs.tweet-catcher.com/monitor/settings.md#api). It is in **Settings → API**, and also appears as **Login Token** on any task that delivers to WebSocket. Send the raw key without a `Bearer` prefix

## Connection flow

**1. Receive hello**

As soon as the socket opens, the server sends:

```json theme={null}
{ "op": 10, "heartbeat_interval": 45000 }
```

**2. Log in**

Send your key:

```json theme={null}
{ "op": 2, "token": "YOUR_KEY" }
```

This must be your first message. Sending any other opcode first closes the connection with `user not logged in`

**3. Start the heartbeat**

Every `heartbeat_interval` milliseconds, send `{ "op": 1 }`. The server answers each one with `{ "op": 11 }`.

If a heartbeat is missed, the server sends `{ "op": 3, "text": "About to close the connection, no heartbeat" }` and closes the socket

**4. Receive ready**

A successful login returns `op` 4. Its `d` object contains `event: "LOGIN"`, `expireAt`, `tasksLimit`, `globalMonitorTasksLimit`, and `tasks`

**5. Receive events**

Each notification arrives as `{ "op": 0, "d": { ...event } }`. See [Events](https://docs.tweet-catcher.com/pro/events.md) for every shape of `d`

## Opcodes

| `op` | Direction | Meaning |
| - | - | - |
| `0` | Server → client | Event. The payload is in `d` |
| `1` | Client → server | Heartbeat |
| `2` | Client → server | Login, with `token` |
| `3` | Server → client | The server is about to close the socket. `text` gives the reason: missing login, bad key, or missed heartbeat |
| `4` | Server → client | Login succeeded. Account info is in `d` |
| `10` | Server → client | Hello, with `heartbeat_interval` |
| `11` | Server → client | Heartbeat acknowledged |

## Example

This Node.js client uses the [`ws`](https://www.npmjs.com/package/ws) package. It logs in, keeps the heartbeat going, and reconnects with a growing delay when the connection drops

```javascript client.js theme={null}
const WebSocket = require("ws")

const URL = "wss://monitor-api.tweet-catcher.com/websocket"
const TOKEN = process.env.TWEET_CATCHER_KEY

let heartbeat = null
let retryDelay = 1000

function connect() {
  const ws = new WebSocket(URL)

  ws.on("message", (raw) => {
    const msg = JSON.parse(raw)

    switch (msg.op) {
      case 10:
        ws.send(JSON.stringify({ op: 2, token: TOKEN }))
        heartbeat = setInterval(() => {
          if (ws.readyState === WebSocket.OPEN) ws.send(JSON.stringify({ op: 1 }))
        }, msg.heartbeat_interval)
        break
      case 4:
        retryDelay = 1000
        console.log("logged in, tasks limit:", msg.d.tasksLimit)
        break
      case 0:
        console.log(msg.d.event, msg.d)
        break
      case 3:
        console.warn("server closing:", msg.text)
        break
    }
  })

  ws.on("error", (err) => console.error("socket error:", err.message))

  ws.on("close", () => {
    clearInterval(heartbeat)
    setTimeout(connect, retryDelay)
    retryDelay = Math.min(retryDelay * 2, 60000)
  })
}

connect()
```

Run it with your key in the environment:

```bash theme={null}
TWEET_CATCHER_KEY=YOUR_KEY node client.js
```

## Reconnecting

The server does not resume a dropped session, and events sent while you are disconnected are not replayed. On every new connection, log in again and restart the heartbeat

> [!WARNING]
>
> If `op` 3 reports a bad key, fix the key before reconnecting. Retrying with the same key fails again

> [!NOTE]
>
> Resetting your API key closes every open WebSocket connection. Update your clients with the new key


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.