# Quickstart

Source: [Official documentation](<https://newlistings.pro/docs/quickstart>)

### Get a key

Get one from [the key bot](<https://t.me/NLF_websocket_bot>). See [Keys](<https://newlistings.pro/docs/keys>) to compare plans.


### Authenticate and connect

Install the Node.js WebSocket client:

```bash
npm install ws@8.21.3
```

Save this as `client.cjs`. It sends your key as a bearer token, prints every JSON response, and reconnects with backoff after a temporary failure. The example uses the FREE host; for STARTER or PRO, change `url` to a [regional host](<https://newlistings.pro/docs#regional-edges>).

```javascript
const WebSocket = require("ws");

const key = process.env.NLF_KEY;
if (!key) throw new Error("Set NLF_KEY before starting the client.");
const url = "wss://ws.newlistings.pro/v2/full";
let retryMs = 1000;

function connect() {
  let stop = false;
  let minimumWaitMs = 0;
  const ws = new WebSocket(url, {
    headers: { authorization: `Bearer ${key}` },
    handshakeTimeout: 10000,
  });

  ws.on("message", (data) => {
    let message;
    try { message = JSON.parse(data.toString()); }
    catch {
      console.error("Invalid JSON response. Stopping.");
      stop = true;
      return ws.close();
    }
    console.log(JSON.stringify(message, null, 2));
    if (message?.type === "success" && message.code === "READY") {
      retryMs = 1000;
    } else if (message?.type === "error") {
      stop = message.code !== "SERVER_UNAVAILABLE";
      ws.close();
    }
  });

  ws.on("unexpected-response", (_request, response) => {
    const status = response.statusCode;
    console.error("Connection rejected: HTTP", status);
    stop = status < 500 && status !== 408 && status !== 429;
    const retryAfter = response.headers["retry-after"] || "";
    minimumWaitMs = /^\d+$/.test(retryAfter)
      ? Number(retryAfter) * 1000
      : Math.max(0, Date.parse(retryAfter) - Date.now()) || 0;
    response.resume();
    ws.terminate();
  });

  ws.on("error", (error) => console.error(error.message));
  ws.on("close", (code) => {
    if (stop || code === 1008) {
      console.error("Stopped. Check your key, request, and connection limits.");
      return;
    }
    const waitMs = Math.max(retryMs, minimumWaitMs) + Math.random() * 250;
    console.log(`Disconnected. Reconnecting in ${Math.ceil(waitMs)} ms...`);
    retryMs = Math.min(retryMs * 2, 30000);
    setTimeout(connect, waitMs);
  });
}

connect();
```

Run it with your key. Press `Ctrl+C` to stop:

```bash
NLF_KEY="YOUR_KEY" node client.cjs
```


### Read READY

Look for `type: "success"` and `code: "READY"`. This confirms your endpoint and account settings. If you receive an error first, resolve it before continuing. See the [READY fields](<https://newlistings.pro/docs/v2/connection-lifecycle#ready-message>).


### Handle events

Parse every text message as JSON. Handle `type: "success"` and `type: "error"` as control messages. Process `type: "announcement"` and `type: "tweet"` as events. This captured Full response from a paid key shows a processed Upbit listing for REZ:

```json
{
  "id": 3663901906511872,
  "type": "announcement",
  "url": "https://upbit.com/service_center/notice?id=26668186",
  "content": {
    "title": "렌조(REZ) 신규 거래지원 안내 (USDT 마켓)"
  },
  "parser": {
    "exchange": "upbit",
    "classification": {
      "event": "listing",
      "type": "spot",
      "category": "crypto",
      "markets": [
        "usdt"
      ]
    },
    "display": "$REZ listed on Upbit spot",
    "assets": [
      {
        "symbol": "REZ",
        "contracts": [],
        "suggested_match": {
          "confidence": "high",
          "project_name": "Renzo",
          "metrics": {
            "circulating_market_cap_usd": 27000000,
            "fdv_usd": 30000000,
            "circulating_supply": 8875943328,
            "total_supply": 9814629224
          },
          "suggested_contracts": [
            {
              "chain": "ethereum",
              "contract": "0x3b50805453023a91a8bf641e279401a0b23fa6f9"
            }
          ]
        }
      }
    ]
  },
  "detected_time_us": 1789014602789862,
  "sent_time_us": 1789014602792927
}
```


### Keep the socket open

The `ws` client answers WebSocket pings automatically. See [Connection lifecycle](<https://newlistings.pro/docs/v2/connection-lifecycle>) for retry rules and [Code examples](<https://newlistings.pro/docs/v2/code-examples>) for more detailed Node.js and Python clients.

Reconnecting resumes live events only. Paid keys can use the [Historical API](<https://newlistings.pro/docs/v2/history>) separately.


Paid keys can use [`/v2/fast`](<https://newlistings.pro/docs/v2/fast>) for raw events.



### [Full endpoint](<https://newlistings.pro/docs/v2/full>)

Schema, filters, and examples.


### [Keys](<https://newlistings.pro/docs/keys>)

Plans, delays, history, and limits.
