How to Scrape Official Steam Community Market Orderbooks

Updated

Endpoints used: GET /v1/market/steam/latest & POST /v1/market/steam/history

Valve's official Steam Community Market exposes a name-based market/orderbook response with the lowest sell listing, highest buy order, active-order counts, and compact depth arrays. The older itemordershistogram route requires a numeric item_nameid. Both routes are undocumented and neither is an official Market API.

Use the name-based orderbook route#

Request https://steamcommunity.com/market/orderbook with q=Load, cc=US, l=english, and currency=1. The qp parameter is a URL-encoded JSON array containing the app ID and exact name: [730,"<market_hash_name>"].

Use the exact listing page as the referer and send x-valve-request-type: queryAction. The response should contain success=true and a data object.

Steam field Meaning
amtMinSellOrder Lowest sell listing in integer currency cents
amtMaxBuyOrder Highest buy order in integer currency cents
cSellOrders Total active sell-listing count
cBuyOrders Total active buy-order count
rgCompactSellOrders Flat sell-side price and quantity pairs
rgCompactBuyOrders Flat buy-side price and quantity pairs

Each compact array alternates price cents and quantity. Split [price, quantity, price, quantity] into aligned levels, reject odd-length arrays, and preserve Steam's order. The declared total order count can differ from the sum of compact quantities; record that difference without inventing missing levels.

Decode a representative response#

A shortened response is {"success":true,"data":{"amtMaxBuyOrder":4124,"amtMinSellOrder":4132,"eCurrency":1,"cBuyOrders":53678,"cSellOrders":1120,"rgCompactBuyOrders":[4124,27,4106,26],"rgCompactSellOrders":[4132,2,4146,1]}}.

The first sell levels decode to 2 orders at $41.32 and 1 at $41.46. The first buy levels decode to 27 orders at $41.24 and 26 at $41.06. cSellOrders=1120 describes the full active sell-listing count, not the sum of the compact levels returned in this shortened example.

Understand itemordershistogram#

The older request is market/itemordershistogram with country, language, currency, item_nameid, and two_factor. Find item_nameid in the exact listing page's Market_LoadOrderSpread(<id>) call. Do not reuse an ID from a different wear or item.

Its response includes highest_buy_order, lowest_sell_order, buy and sell graphs, small HTML tables, and summary fields. Prices are commonly integer minor units even when graph labels are formatted strings. The graph quantities are cumulative, so calculate per-level quantity only if the application needs it.

The name-based route removes the numeric-ID discovery step and is what cs2.sh currently uses for direct Steam depth collection. The legacy route remains useful when maintaining an older integration.

Validate before storing a snapshot#

Require success=true, confirm the response currency, validate numeric prices, and verify every compact pair. success=false can mean Steam does not resolve that market name; it is not proof of a network outage. HTML, 403, 429, and 5xx responses need separate retry handling.

Attach an observation timestamp and exact market hash name to every accepted snapshot. Active orders are not completed sales, and a full ladder can change before an application acts on it.

Skip the collector for stored depth#

GET /v1/market/steam/latest returns full-depth Steam orderbooks across every tracked regular item. Historical Steam depth stores hourly and daily snapshots from June 9, 2026. Those are the parts a one-time free request cannot provide later.

Self-scraping remains useful when raw responses or exact request timing are part of the product. Otherwise, cs2.sh avoids numeric-ID discovery, currency checks, malformed ladders, per-item scheduling, blocks, retries, and years of snapshot storage.

The same data from cs2.sh#

GET /v1/market/steam/latest returns the same ladder shape for every tracked regular item, on all plans, without numeric-ID discovery or per-item scheduling.

json
"depth": {
  "ask_levels": 2,
  "bid_levels": 2,
  "asks": { "prices": [169.14, 169.4], "volumes": [1, 1] },
  "bids": { "prices": [155.05, 154.88], "volumes": [1, 1] }
}

For depth over time, POST /v1/market/steam/history returns the last complete orderbook collected inside each bucket, from June 9, 2026:

Property Value
Intervals 1h (max range 90 days), 1d (unlimited)
Shape Same top and depth objects as the latest endpoint
Items per request 100
Access Requires a Scale or Enterprise API key

This is sampled history, not OHLC. Each bucket is one real observed book rather than an aggregation, so a 1d bucket is the last snapshot of that day and not a summary of it. 503 service_unavailable on the latest endpoint means the current snapshot is missing, stale, or empty.

Disclosure: this free DIY guide is published by cs2.sh. These interfaces are undocumented and subject to the Steam Subscriber Agreement. Review authorization before running an automated collector. Live fields and both routes were checked on August 5, 2026.