# Steam Market vs cash-market prices: how to compare them correctly

> Steam Market prices are wallet credit, not cash. Learn how to compare Steam and cash-market CS2 prices after fees, using execution-adjusted quotes.

*Prices & quotes · Intermediate · Updated 2026-09-25*

Put a Steam Community Market price next to a cash marketplace price for the same skin and the Steam number is usually higher, sometimes by a wide margin. That gap is not free money. The two prices are denominated in different things: Steam settles in Steam wallet balance, which can be spent on Steam but not withdrawn to a bank, while cash marketplaces pay sellers out in money. Comparing them as if they were the same currency is the most common mistake in CS2 price tooling, and it produces arbitrage signals that disappear the moment you try to trade them.

This guide shows how SkinPricer separates the two, how to pull both books side by side, and how to use the fee-aware `executionAdjusted` quote to compare what a trade actually pays on each side.

## Why a Steam price and a cash price are different numbers

Three things separate a Steam price from a cash price for the same item. First, the settlement asset: a Steam sale credits your wallet, and wallet balance cannot leave Steam. Second, fees: the seller of a Steam listing does not receive the listed price, and the execution model SkinPricer uses applies an estimated 15% seller fee to Steam bids. Third, liquidity: a Steam buy order may be real and deep, but filling it converts your skin into store credit, which is only worth its face value to someone who was going to spend it on Steam anyway.

SkinPricer encodes this in how it picks the best bid. Each venue's bid is classified as cash-executable (a seller can withdraw the proceeds) or not. In the default all-markets view, the cross-market `bestBid` on [`/v1/nbbo`](/api-docs/nbbo) and [`/v1/pricing`](/api-docs/price) only considers cash-executable venues, such as BUFF163, CSFloat, Skinport, DMarket, Market.CSGO, and Waxpeer. Steam wallet-credit bids and trade-bot site balance stay in the per-market data, but they cannot win the cross-market bid unless you ask for them.

| Question | Use this |
| --- | --- |
| What is the best cash bid anywhere? | Default `GET /v1/nbbo` (no `markets` list). |
| What is Steam's own ask and bid? | `GET /v1/pricing/:marketHashName` and read the `steamcommunity` rows in `markets[]` and `buyOrders[]`. |
| What would I really net selling on each side? | `GET /v1/nbbo` with an explicit `markets` list, then read `executionAdjusted.bestBid.price`. |

## Step 1: pull both books side by side

The pricing snapshot returns one representative ask per venue in `markets[]` and the standing bids in `buyOrders[]`. Restrict it to Steam plus the cash venues you care about, then compare Steam's ask with the cheapest cash ask. The ratio between them is the Steam premium for that item right now.

**curl**

```bash
export SKINPRICER_API_KEY="sp_live_•••"   # from your account's API keys page

curl -s "https://pricing.skinpricer.com/v1/pricing/AK-47%20%7C%20Redline%20(Field-Tested)?markets=steamcommunity,csfloat,buff163,skinport" \
  -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 CASH_VENUES = ["csfloat", "buff163", "skinport"];

const item = await client.pricing.get("AK-47 | Redline (Field-Tested)", {
  markets: ["steamcommunity", ...CASH_VENUES],
});

const steam = item.markets.find((q) => q.market === "steamcommunity");
const cashAsks = item.markets.filter((q) => CASH_VENUES.includes(q.market));
const cheapestCash = cashAsks.reduce<(typeof cashAsks)[number] | undefined>(
  (best, q) => (best === undefined || q.price < best.price ? q : best),
  undefined,
);

if (steam && cheapestCash) {
  const premiumPct = (steam.price / cheapestCash.price - 1) * 100;
  console.log("Steam ask:", formatUsd(steam.price));
  console.log("Cheapest cash ask:", formatUsd(cheapestCash.price), "on", cheapestCash.market);
  console.log("Steam premium:", premiumPct.toFixed(1) + "%");
}
```

**Python**

```python
import os
from urllib.parse import quote

import requests

CASH_VENUES = {"csfloat", "buff163", "skinport"}
name = "AK-47 | Redline (Field-Tested)"

res = requests.get(
    f"https://pricing.skinpricer.com/v1/pricing/{quote(name, safe='')}",
    params={"markets": ",".join(["steamcommunity", *CASH_VENUES])},
    headers={"Authorization": f"ApiKey {os.environ['SKINPRICER_API_KEY']}"},
    timeout=10,
)
res.raise_for_status()
asks = {q["market"]: q["price"] for q in res.json()["markets"]}

steam = asks.get("steamcommunity")
cash = [p for m, p in asks.items() if m in CASH_VENUES]
if steam and cash:
    print(f"Steam premium: {(steam / min(cash) - 1) * 100:.1f}%")
```

*A venue with no live listing for the item is absent from markets[], so always handle a missing Steam or cash quote.*

**Response 200** (`GET /v1/pricing/:marketHashName`)

```json
{
  "canonicalItemId": "cmlofca920lka01yozajhixt3",
  "name": "Glock-18 | Water Elemental (Factory New)",
  "aggregate": {
    "minPrice": 6500,
    "maxPrice": 8012,
    "avgPrice": 7102,
    "medianPrice": 7119,
    "stdDev": 439.12,
    "marketCount": 10,
    "freshMarketCount": 9,
    "listingCount": 710,
    "updatedAt": "2026-06-23T21:59:48.717Z"
  },
  "markets": [
    {
      "market": "csfloat",
      "price": 6500,
      "currency": "USD",
      "fetchedAt": "2026-06-23T21:52:27.427Z",
      "ingestedAt": "2026-06-23T21:55:56.923Z",
      "quoteSize": 132,
      "ingestLatencyMs": 209496,
      "isStale": false,
      "sourceUpdatedAt": "2026-06-23T21:01:13.000Z",
      "sourceTimeKind": "last_modified",
      "sourceAgeSeconds": 3074
    }
  ],
  "buyOrders": [
    {
      "market": "buff163",
      "price": 6440,
      "currency": "USD",
      "fetchedAt": "2026-06-23T21:59:48.717Z",
      "ingestedAt": "2026-06-23T21:59:48.000Z",
      "quoteSize": 47,
      "totalQuantity": 47,
      "ingestLatencyMs": 0,
      "isStale": false
    }
  ],
  "bestAsk": {
    "market": "csfloat",
    "price": 6500,
    "updatedAt": "2026-06-23T21:52:27.427Z",
    "isStale": false
  },
  "bestBid": {
    "market": "buff163",
    "price": 6440,
    "updatedAt": "2026-06-23T21:59:48.717Z",
    "isStale": false
  },
  "spreadBps": 93,
  "marketCount": 10,
  "freshMarketCount": 9,
  "calculatedAt": "2026-06-23T22:07:13.752Z"
}
```

*The documented pricing response. Each markets[] entry is one venue's representative ask in USD cents.*

## Step 2: compare what each side actually pays

Sticker prices are only half the story. The [`executionAdjusted`](/api-docs/reading-prices) block on the NBBO response re-prices the best bid as what a seller would net after the venue's commission and any flat withdrawal fee, and re-ranks the best ask by executability. Call the NBBO twice: once in the default view, which gives the best cash bid, and once with an explicit list that includes Steam, which lets the Steam bid compete. Then compare the adjusted bids.

**Node (SDK)**

```ts
const name = "AK-47 | Redline (Field-Tested)";

const [cashView, withSteam] = await Promise.all([
  client.nbbo.get({ marketHashName: name }),
  client.nbbo.get({ marketHashName: name, markets: ["steamcommunity", ...CASH_VENUES] }),
]);

const cashBid = cashView.executionAdjusted?.bestBid;
const anyBid = withSteam.executionAdjusted?.bestBid;

if (cashBid) {
  console.log("Best cash bid nets", formatUsd(cashBid.price), "on", cashBid.market,
    "(gross", formatUsd(cashBid.rawPrice) + ")");
}
if (anyBid && anyBid.market === "steamcommunity") {
  console.log("Steam bid nets", formatUsd(anyBid.price), "in wallet credit, not cash");
}
```

**curl**

```bash
# Default view: the best bid is cash-executable only.
curl -s "https://pricing.skinpricer.com/v1/nbbo?market_hash_name=AK-47%20%7C%20Redline%20(Field-Tested)" \
  -H "Authorization: ApiKey $SKINPRICER_API_KEY"

# Explicit list: every listed venue's bid competes, Steam included.
curl -s "https://pricing.skinpricer.com/v1/nbbo?market_hash_name=AK-47%20%7C%20Redline%20(Field-Tested)&markets=steamcommunity,csfloat,buff163,skinport" \
  -H "Authorization: ApiKey $SKINPRICER_API_KEY"
```

> **A Steam bid above a cash ask is not arbitrage:** Buying on a cash market and selling into a Steam buy order turns money into wallet credit. Unless you were going to spend that credit on Steam anyway, the trade loses value. That is exactly why the default views exclude wallet-credit bids from the cross-market best bid.

> **Fee rates are estimates:** The execution model's commission rates are published estimates, not audited per-account fees. Responses flag this with `reasons` such as `assumed_fees` and a `feeModelVersion`. If you have a negotiated rate, apply your own fee to `rawPrice` instead.

## Rules of thumb for honest comparisons

- Compare like with like: a Steam ask against a Steam bid, or a cash ask against a cash bid. Mixing them measures the wallet discount, not a spread.
- Report the Steam premium as its own number. Traders find it useful, and it keeps wallet prices from leaking into cash valuations.
- Use `rawPrice` for display and the adjusted `price` for decisions. The difference is the fee you are about to pay.
- Check freshness on both sides. A Steam quote and a cash quote collected minutes apart can disagree simply because one moved first; `isStale` and `updatedAt` are on every best price.

## When to reach for a different endpoint

If Steam is the only market you need, the [Steam prices guide](/resources/steam-market-prices-without-scraping) covers current asks, bids, and sale history from the same API. To turn several signals into one number for a valuation, see [how to estimate fair value](/resources/cs2-skin-fair-value). The underlying rules for cash-executable bids, spreads, and the execution-adjusted book are documented in [Ask, bid & NBBO](/api-docs/reading-prices).

## Endpoints used

- [Reading prices: ask, bid & NBBO](/api-docs/reading-prices.md)
- [GET /v1/nbbo](/api-docs/nbbo.md)
- [GET /v1/pricing/:marketHashName](/api-docs/price.md)

## Related guides

- [How to get Steam Community Market prices without scraping](/resources/steam-market-prices-without-scraping.md)
- [How to find the best bid and ask for a CS2 skin across every market](/resources/cs2-best-bid-and-ask.md)
- [How to estimate what a CS2 skin is really worth](/resources/cs2-skin-fair-value.md)
- [How to get live CS2 skin prices from every marketplace](/resources/live-cs2-skin-prices.md)
