Skip to content
New Listings Feed
Getting startedQuickstart

Quickstart

Connect to /v2/full and read your first event.

Get a key

Get one from the key bot. See Keys to compare plans.

Authenticate and connect

Install the Node.js WebSocket client:

npm install [email protected]

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.

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:

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.

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:

{
  "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 for retry rules and Code examples for more detailed Node.js and Python clients.

Reconnecting resumes live events only. Paid keys can use the Historical API separately.

Paid keys can use /v2/fast for raw events.