BUFF sale history is now available - POST /v1/archive/buff returns sale prices and daily total supply since September 2024.

How to Get Current CSFloat Prices for CS2 Items

Updated

Endpoints used: GET /v1/prices/latest & POST /v1/prices/latest

Related pages: CSFloat price API

The csfloat source in cs2.sh's GET or POST /v1/prices/latest returns ask, the lowest active sell listing, bid, the highest standing buy order, and ask_volume, the number of active listings. CSFloat publishes no buy-order count, so there is no bid_volume.

CSFloat is one of the more useful CS2 sources because it publishes both sides of the market and supports variants, so a Phase 2 Doppler carries its own price rather than inheriting the base item's.

What cs2.sh provides for CSFloat#

Property Value
Endpoints GET /v1/prices/latest (all items), POST /v1/prices/latest (up to 100 named items)
Fields ask, bid, ask_volume
Not published bid_volume
Refresh About every 5 minutes; CSFloat variant asks and bids about every 10-15 minutes
Variants Doppler, Gamma Doppler, and Case Hardened
Currency Always USD
Access Available on all plans

The missing bid_volume is the constraint worth designing around. You know the highest buy order and nothing about how many items stand behind it, so a CSFloat bid prices the next unit rather than a quantity.

Request the item#

bash
curl -X POST https://api.cs2.sh/v1/prices/latest \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  -H "Accept-Encoding: gzip" --compressed \
  -H "Content-Type: application/json" \
  -d '{"items": ["USP-S | Printstream (Factory New)"]}'
json
"csfloat": {
  "updated_at": "2026-07-26T18:53:05.094Z",
  "collected_at": "2026-07-26T18:53:05.134Z",
  "ask": 107.99,
  "ask_volume": 227,
  "bid": 105
}
Field Type Description
ask number | null Lowest active sell listing, USD.
bid number | null Highest standing buy order, USD.
ask_volume integer | null Number of active sell listings.
updated_at string (date-time) When CSFloat last updated the price.
collected_at string (date-time) When cs2.sh collected it.

Reading the data correctly#

updated_at and collected_at answer different questions. A price can be freshly collected and still stale at source, which a wide gap between the two reveals. Reject on whichever bound matters to you and keep the timestamp attached to any number you display or store.

The distance between ask and bid is the gap between what sellers want and what buyers have committed to. Compute it only from values inside the same source object: an ask from this response against a bid from a request eight minutes ago describes neither moment. Because CSFloat variant prices refresh on a slower cycle than base items, a variant's ask and the base item's ask in one response may have been observed at noticeably different times.

Base item source objects are dense, so csfloat is present whenever any source has data for the item, with null in fields CSFloat did not supply. Variant source objects are sparse: csfloat appears under a variant only when CSFloat has data for that exact phase or tier. A missing Phase 3 price cannot inherit the base Doppler price or another phase's.

Neither ask nor bid is a completed sale. Both are offers that can be filled, changed, or cancelled. When the question is what items actually sold for, POST /v1/archive/csfloat returns a daily average sale price and sale count from 2022.

When values are absent#

bid is null when no buy order stands on the item, which is common on illiquid skins and individual phases. ask is null when nothing is listed. Both are real market states and should stay absent rather than becoming zero, which would silently produce a free item in any downstream comparison.

When items are missing or fail#

A 200 response can carry both items and errors[], one entry per failed item. unknown_item means the name did not resolve, invalid_format means the value was malformed, and not_in_cache means the item is valid but absent from the current dataset.

Request-level failures return error, message, and a request_id. A 403 means the endpoint is not in your plan, and 429 means the per-second limit was exceeded and should be retried with a bounded delay.

Worked example: the CSFloat side of a cross-market comparison#

Read csfloat.ask for the buy-side price and csfloat.bid for what a seller could accept now, confirming collected_at on both. Compare ask against other sources' ask values in the same response to find the cheapest listing, and never against another source's bid, which answers a different question.

Pair ask with ask_volume to judge whether the price represents one listing or a deep book, then apply fees and transfer assumptions outside the API, keeping the raw value and the derived one as separate fields.

Full field reference: GET /v1/prices/latest. Variant naming and versions: variants. Refresh rates: data coverage.