Websocket service

Breaking websocket API change

Very soon, the websocket API is moving away from an event-per-frame model to resolve a scaling issue. Going forward, multiple events will be batched into single frames as an array. Supporting this requires a small change to your client code.

Connect to the websocket API with batch-test in the request headers to receive messages in the new format, and make the appropriate change to your event handler.

You can see a forwards-compatible example in the below Quick Start example.

The events websocket service emits a live stream of backpack.tf system events. You can use this to gather up-to-date information about Classifieds listings.

Be warned that the websocket server will emit a large amount of data and does not provide any event filtering -- use your own tools to process the data you need. This could be as simple as piping all events into a database that you can query in another part of your application.

Connection URI



The following events are provided by the websocket:


Fired whenever a listing is created or updated. The exception to this is whenever listings are bumped, or when currency values are updated from a price suggestion (this causes all listings to have their value recalculated).

Re-publishing an archived listing is considered an update.


Fired whenever a listing is deleted. Moving a listing to the archive is also considered to be deleting the listing.

Event IDs

Each event has a unique 12-byte alphanumeric ID. The first four bytes of the ID is a 32-bit timestamp. Check here for more information on this format.

Quick Start

Requires a websocket library.

import WebSocket from 'ws';

const ws = new WebSocket('wss://ws.backpack.tf/events');

ws.on('open', function open() {
    console.log("websocket running")

function handleEvent(e) {
    switch (e.event) {
        case 'listing-update':
            console.log(`listing ${e.payload.id} by ${e.payload.user.id} was updated (or created).`)
        case 'listing-delete':
            console.log(`listing ${e.payload.id} by ${e.payload.user.id}  was deleted.`)

ws.on('message', data => {
    const json = JSON.parse(data)

    // forwards-compatible support of the batch mode, if you did not set the batch-test header.
    if (json instanceof Array) {
        json.forEach(handleEvent) // handles the new event format
    } else {
        handleEvent(json) // old event-per-frame message format - DEPRECATED!

Connecting with the batch-test header

Temporarily, the batch-test header enables the new batch frame method. You should keep this enabled if you have confirmed that it works for your script.

const ws = new WebSocket(
  { headers: { 'batch-test': true } }

Handling connection loss

On occasion, the websocket server may restart. Assume this might happen, as we may update or perform maintenance on the websocket server at any moment.

If using Node.js, you can use reconnecting-websocket to gracefully manage the websocket connection.