Skip to main content
The live market is the set of cheapest current listings across connected marketplaces, kept warm and repriced for the viewer. It has two surfaces:
  • GET /market — a snapshot of the feed, cheapest first.
  • GET /market/live — a WebSocket that pushes price deltas in real time.
Use them together: load a snapshot, open the socket, then apply each delta on top of the snapshot. Prices on both surfaces already include the viewer’s fee, so you render them as-is.

Snapshot

GET /market returns the curated feed sorted cheapest first.
integer
default:"1"
1-based page number.
integer
default:"100"
Listings per page, 1–500, or -1 to return the whole feed in one response.
Each entry’s price is a decimal number with the viewer’s fee already applied, and id is the buyable listing id you pass to the trade endpoints. See Data models for the full MarketListing shape.

Live stream

The socket pushes a delta whenever a listing in scope appears, reprices, or is removed. It carries no snapshot of its own — pair it with GET /market to establish initial state.

Scopes

string
default:"all"
all or watchlist.
Pick watchlist to track the same set GET /market serves. Pick all only if you want the raw firehose and can absorb the volume.

Authentication

The live socket uses the same JWT ticket as the WebSocket event stream — the ticket carries a market scope alongside deposit and trade, so one ticket works for both sockets.
1

Mint a ticket

Call POST /auth/ws-token with On-Behalf-Of set to the sub-user you’re acting as.
2

Open the socket

Pass the token as a bearer.<jwt> subprotocol (preferred — query strings leak into logs) or as ?token=:
3

Wait for the ready frame

On a successful upgrade the server sends:

Protocol

  • Read-only. Sending any frame closes the socket with 4002 Read-only.
  • Heartbeats. The server sends WS pings; reply with pongs (most clients do this automatically).
  • Frame shape. Every push is { event, data, ts }, where ts is Unix epoch milliseconds.

Events

Treat market.new and market.update identically — upsert the listing keyed by data.id. On market.remove, drop the listing by data.listingId.

Keeping a view in sync

1

Open the socket and buffer

Open scope=watchlist and buffer deltas until the snapshot loads, so nothing is lost in the gap.
2

Load the snapshot

Page through GET /market into your map keyed by id.
3

Apply buffered and live deltas

Replay the buffered deltas, then keep applying new ones. An update for a listing you don’t have is just an insert; a remove for one you don’t have is a no-op.
Prices are snapshotted at connect time using the acting sub-user’s fee tier. A mid-session fee change takes effect on the next reconnect.

Close codes

A sub-user may hold up to 5 concurrent live sockets. For the reconnect pattern (mint a fresh ticket on 4001, back off on network blips), see the WebSocket guide.