Realtime overview
Auction-scoped activity at Handbid is broadcast over Socket.IO, keyed by auction GUID. Clients that want live updates connect to the Handbid Socket.IO server, join the rooms they care about, and listen for events.
What’s broadcast
Section titled “What’s broadcast”Every realtime event is scoped to one auction. The room name is
literally {auctionGuid}_v2. Once you’re in the room, you receive:
| Event | When | Payload |
|---|---|---|
event.bid | A bid lands on an item in this auction. | item id, amount, new winner |
event.sealed_bid | A sealed-bid offer is placed. | item id, amount (masked for non-managers) |
event.competitive_bid | A competitive-bid offer is placed. | item id, amount, identity |
event.item | Item state changes (price, status, winner). | item id, new state |
event.sold | Item closes with a winner. | item id, winner id, sale price |
event.timer | Auction timer is set, paused, or expires. | timer state |
event.close | Auction or item closing event. | what closed, when |
event.promoted | Item is promoted on a Handbid TV display. | item id |
event.broadcast | Manager broadcast to all attendees. | text |
Each event arrives as a JSON payload. The shape is stable; new fields may be added (additive), existing fields won’t change type or disappear.
Get the auction GUID
Section titled “Get the auction GUID”Every V3 response that surfaces an auction returns its GUID. Use that value verbatim:
{ "id": 5, "guid": "c1b41927-689f-4c20-8621-534e05ffbacc", "name": "Annual Passholder Picks", …}On item-shape responses (/v3/item/{id}) the field is named auctionGuid
to keep the auction* prefix consistent with the surrounding fields.
The room name is {guid}_v2:
c1b41927-689f-4c20-8621-534e05ffbacc_v2User-scoped events
Section titled “User-scoped events”A small set of events is broadcast to a user room, not an auction room:
| Room | Events |
|---|---|
user:{userGuid} | event.user, event.winner, event.notification, event.favorite |
user.guid is the recipient’s user GUID. The contract is: a client should
join their own user room on connect, and rejoin auction rooms as the user
navigates between screens.
Endpoint vs server
Section titled “Endpoint vs server”The Socket.IO server is separate from the REST API. Production:
- REST API:
https://api-ha-prod-p8.handbid.dev - Socket.IO:
https://node-ha-prod-p8.handbid.dev:3001(path:/socket.io/)
The Socket.IO server emits events; it doesn’t accept commands. To “do something” you call REST. The REST mutation triggers a server-side event, which lands in the room a moment later.
Authentication
Section titled “Authentication”The Socket.IO connection isn’t bearer-authenticated — Handbid’s realtime layer trusts any connected client to join any auction room. Sensitive fields (sealed-bid amounts, etc.) are masked server-side before broadcast, so room membership alone doesn’t leak private data.
If your integration has a use case for tighter realtime auth (per-user private rooms, signed event payloads, etc.), tell us.
Practical patterns
Section titled “Practical patterns”Join + cleanup
Section titled “Join + cleanup”connect()on('connect', () => socket.emit('join', { room: 'user:' + currentUserGuid }))
// when user opens an auction detail:socket.emit('join', { room: auction.guid + '_v2' })
// when user leaves:socket.emit('leave', { room: auction.guid + '_v2' })Always leave rooms you’re no longer rendering. The server scales by trimming fanout — rooms with thousands of stale members are bad for everyone.
Debouncing high-frequency events
Section titled “Debouncing high-frequency events”Bid storms at the end of a closing auction can produce hundreds of
event.bid per minute. Coalesce on the client — at most 60fps re-renders,
ideally 10fps for non-focused tabs. The events still arrive; you just
don’t have to redraw on every one.
Reconciling after reconnect
Section titled “Reconciling after reconnect”If your client’s Socket.IO connection drops and reconnects, re-fetch the state via REST before you trust subsequent events. A reconnected client missed N events while disconnected; the REST re-fetch resyncs.
Out of scope
Section titled “Out of scope”- Per-room presence (who else is here). Not surfaced.
- Event history / replay. If you missed it, you missed it. Fetch via REST to catch up.
- Server-side push to APNs/FCM. That’s a separate (Handbid-internal) delivery layer; you don’t subscribe to it from a Socket.IO room.
See also
Section titled “See also”- Quickstart — get a token, list auctions, find a GUID
- HAN-1878 in the API reference — the
endpoints that expose
guid/auctionGuid