# 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.

*Liquidity & depth · Intermediate · Updated 2026-09-25*

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`](/api-docs/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.

**curl**

```bash
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"
```

**Node (SDK)**

```ts
// 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}`,
  );
}
```

**Python**

```python
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}")
```

*URL-encode the item name in raw HTTP; the SDK and requests encode it for you.*

**Response 200** (`GET /v1/nbbo/depth`)

```json
{
  "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"
}
```

*The documented 200 response. Its top bid is a stale Steam Community Market buy order, which settles in wallet credit: that is why `spreadBps` is negative while `crossed` stays false. Under the cash-only rule described in step 3, a wallet or stale bid cannot set `crossed`.*

## 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.

```ts
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`);
```

*If the requested size exhausts the levels you fetched, raise `depth` (up to 50) before concluding the book is empty.*

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.

> **Stale levels are still shown:** Quotes up to six hours old stay in the ladder so thin items are not blank, but they carry `isStale: true` once they pass 30 minutes. A level built entirely from stale quotes is a memory of the book, not an order you can hit. Drop or discount stale levels before pricing a fill.

- 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](/api-docs/nbbo) considered.
- `quantity` is units, `ordersCount` is 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.
- `marketCount` at 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](/resources/cs2-best-bid-and-ask) 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](/resources/cs2-skin-liquidity). Full field tables live in the [order-book depth API reference](/api-docs/depth).

## Endpoints used

- [GET /v1/nbbo/depth](/api-docs/depth.md)
- [GET /v1/nbbo](/api-docs/nbbo.md)

## Related guides

- [How to find the best bid and ask for a CS2 skin across every market](/resources/cs2-best-bid-and-ask.md)
- [How to check CS2 skin liquidity and time-to-sell](/resources/cs2-skin-liquidity.md)
- [How to value a CS2 inventory at live market prices](/resources/cs2-inventory-value.md)
