How to read CS2 order-book depth across every marketplace
Read aggregated CS2 order-book depth: bid and ask ladders merged across marketplaces, cumulative quantity, and what thin books mean for your fills.
On this page
The best bid and ask tell you where the market is. They do not tell you how much you can trade there. A skin can show a $65.00 ask on one venue with a single unit behind it and the next listing at $71.00, so a buyer who needs ten units pays far more than the headline suggests. Order-book depth answers the question the top of book cannot: how much size sits at each price, and on which venues.
SkinPricer merges the ask and bid ladders of every integrated marketplace into one ranked book per item and serves it from GET /v1/nbbo/depth. This guide shows how to request it, how to read each level, how to estimate the real cost of a multi-unit fill, and which flags tell you a level is not what it seems.
What one depth level contains#
The response has an asks array sorted cheapest first and a bids array sorted highest first. Each entry is a price level. When two venues quote the identical price, their quantities are merged into one level, and the quotes array shows exactly which venue contributed what. All prices are integer USD cents.
| Field | Meaning |
|---|---|
rank | Position in the ladder, 1 being the top of book. |
price | The level's price in cents. |
quantity / ordersCount | Units available at this price, and the number of listings or buy orders behind them, summed across venues. |
marketCount | How many venues quote this exact price. |
cumulativeQuantity | Units available at this level and every better one. Read it as "how much can I fill up to this price". |
updatedAt / isStale | The newest contributing quote time. A level is stale only when every quote behind it is older than 30 minutes. |
quotes[] | The per-venue pieces of the level: market, the venue's own level, price, quantity, ordersCount, and freshness. |
Step 1: request the ladder#
Identify the item by market_hash_name (or canonical id) and choose how many levels you want per side with depth, from 1 to 50 (default 10). The endpoint is available from the Developer plan up. Responses are cached for about 15 seconds on our side, so polling faster than that returns the same book.
export SKINPRICER_API_KEY="sp_live_•••" # from your account's API keys page
curl -s "https://pricing.skinpricer.com/v1/nbbo/depth?market_hash_name=AK-47%20%7C%20Redline%20(Field-Tested)&depth=20" \
-H "Authorization: ApiKey $SKINPRICER_API_KEY"// npm i @skinpricer/sdk
import { SkinpricerClient, formatUsd } from "@skinpricer/sdk";
const client = new SkinpricerClient({
apiKey: process.env.SKINPRICER_API_KEY!,
authScheme: "ApiKey",
});
const book = await client.nbbo.depth({
marketHashName: "AK-47 | Redline (Field-Tested)",
depth: 20,
});
for (const level of book.asks.slice(0, 5)) {
const venues = level.quotes.map((q) => q.market).join(", ");
console.log(
`#${level.rank} ${formatUsd(level.price)} x${level.quantity}`,
`(cumulative ${level.cumulativeQuantity}) on ${venues}`,
);
}import os
import requests
res = requests.get(
"https://pricing.skinpricer.com/v1/nbbo/depth",
params={"market_hash_name": "AK-47 | Redline (Field-Tested)", "depth": 20},
headers={"Authorization": f"ApiKey {os.environ['SKINPRICER_API_KEY']}"},
timeout=10,
)
res.raise_for_status()
book = res.json()
for level in book["asks"][:5]:
venues = ", ".join(q["market"] for q in level["quotes"])
print(f"#{level['rank']} ${level['price'] / 100:.2f} x{level['quantity']} on {venues}"){
"marketHashName": "Glock-18 | Water Elemental (Factory New)",
"canonicalItemId": "cmlofca920lka01yozajhixt3",
"depth": 4,
"marketCount": 14,
"asks": [
{
"rank": 1,
"price": 6240,
"quantity": 23,
"ordersCount": 23,
"marketCount": 1,
"cumulativeQuantity": 23,
"updatedAt": "2026-06-23T17:53:23.000Z",
"isStale": true,
"quotes": [
{
"market": "dmarket",
"level": 1,
"price": 6240,
"quantity": 23,
"ordersCount": 23,
"updatedAt": "2026-06-23T17:53:23.000Z",
"isStale": true
}
]
}
],
"bids": [
{
"rank": 1,
"price": 9145,
"quantity": 1,
"ordersCount": 1,
"marketCount": 1,
"cumulativeQuantity": 1,
"updatedAt": "2026-06-23T20:23:03.000Z",
"isStale": true,
"quotes": [
{
"market": "steamcommunity",
"level": 1,
"price": 9145,
"quantity": 1,
"ordersCount": 1,
"updatedAt": "2026-06-23T20:23:03.000Z",
"isStale": true
}
]
}
],
"spreadBps": -3177,
"locked": false,
"crossed": false,
"calculatedAt": "2026-06-23T22:07:15.107Z"
}spreadBps is negative while crossed stays false. Under the cash-only rule described in step 3, a wallet or stale bid cannot set crossed.Fetch the current merged book for AK-47 | Redline (Field-Tested) in your browser.
Step 2: estimate the real cost of a multi-unit fill#
The most useful thing depth gives you is the price of size. To buy N units you walk the ask ladder from the top, taking each level's quantity until you have enough. The average price you pay, and the worst price you touch, are what matter for a trade or a valuation, not the best ask. Do the arithmetic in integer cents and only convert to dollars for display.
import type { NbboDepthLevel } from "@skinpricer/sdk";
interface FillEstimate {
filled: number;
costCents: number;
avgPriceCents: number | null;
worstPriceCents: number | null;
}
/** Walk levels best-first and price a fill of `units`. Works for asks
* (cost to buy) and bids (proceeds to sell) alike. */
export function walkLadder(levels: NbboDepthLevel[], units: number): FillEstimate {
let remaining = units;
let costCents = 0;
let worstPriceCents: number | null = null;
for (const level of levels) {
if (remaining <= 0) break;
const take = Math.min(remaining, level.quantity);
costCents += take * level.price;
remaining -= take;
worstPriceCents = level.price;
}
const filled = units - remaining;
return {
filled,
costCents,
avgPriceCents: filled > 0 ? Math.round(costCents / filled) : null,
worstPriceCents,
};
}
const buy10 = walkLadder(book.asks, 10);
if (buy10.filled < 10) console.log(`Only ${buy10.filled} units in the top 20 levels`);Remember that levels merge venues. A level of 12 units at one price might be 9 on one marketplace and 3 on another, and you would need accounts and balances on both to take all 12. Look at quotes[] when execution venue matters, and group by market if you can only trade on some of them.
Step 3: know which bids are cash#
The depth ladder includes every venue's bids, including Steam Community Market buy orders that pay in wallet credit rather than cash. That is deliberate: depth is a view of the whole book. It also means the top bid in depth can sit above the top ask, which gives a negative spreadBps. Unlike the NBBO endpoint, the depth spread is never clamped, so it can be large or negative.
The crossed flag is stricter. It is true only when a fresh bid on a cash-executable venue, after that venue's estimated seller fees, is above the best fresh cash ask. A negative spread with crossed: false therefore usually means a non-cash bid on top, not free money. If you only care about cash, restrict the book with markets, for example markets=buff163,csfloat,skinport,dmarket,marketcsgo,waxpeer, and every level will come from the venues you listed.
- Depth counts listings and buy orders that publish a quantity. A venue that exposes only its best bid, with no ladder behind it, is left out of depth, so depth can show fewer bid venues than the NBBO considered.
quantityis units,ordersCountis the number of listings or orders. On listing-based venues they are often equal; on buy-order books one order can bid for several units.marketCountat the top of the response is the number of distinct venues in the book, not the number per level.
Step 4: turn depth into a decision#
A practical pattern is to compute the average fill price for the size you actually trade and compare it with the best price. If buying ten units costs 4% more on average than the best ask, the item is thinner than its headline suggests, and any resale margin has to clear that slippage first. The same walk over bids tells you what a quick sale of ten units would realistically net before fees. Tracking that slippage over time is a far better liquidity signal than listing counts alone.
When to reach for a different endpoint#
If you only need one price per side, the best bid and ask guide is lighter and includes fee-adjusted prices. If the question is how long a listing will take to sell rather than how much the book can absorb right now, read the liquidity and time-to-sell guide. Full field tables live in the order-book depth API reference.
Endpoints used in this guide
Plans start at $50/month on the Developer tier. Want to try first? Ask in our Discord for a free 2-day Developer key.
Related guides
- Prices & quotesBeginner
How to find the best bid and ask for a CS2 skin across every market
Find the highest buy order and lowest ask for any CS2 skin across every marketplace at once, with freshness, spread, and confidence. Runnable code included.
GET /v1/nbbo6 min read - Liquidity & depthIntermediate
How to check CS2 skin liquidity and time-to-sell
Check how liquid a CS2 skin is and how long it takes to sell, per market and across markets, one item or thousands at once. With runnable API code.
GET /v1/liquidity/:marketHashNameGET /v1/liquidity/summary/:marketHashName6 min read - Build with the APIIntermediate
How to value a CS2 inventory at live market prices
Value a CS2 inventory at live market prices: batch lowest asks and highest buy orders, add liquidity, and report a realistic liquidation value.
GET /v1/aggregations/min-pricesGET /v1/aggregations/max-orders6 min read