# How to price a CS2 skin by its float range

> Price a CS2 skin by its exact float: how float-range buckets work per market, how to query them, and how to spot low-float premiums. Runnable API code.

*Floats & attributes · Intermediate · Updated 2026-09-25*

Every CS2 skin has a float value between 0 and 1 that sets its wear. The market hash name only tells you the exterior band the float falls in, such as Field-Tested (0.15 to 0.38), but buyers care about where inside that band a skin sits. A 0.151 Field-Tested AK-47 | Redline looks close to Minimal Wear and usually sells above a 0.37 one, even though both share one market hash name and one headline price.

To price a specific item, you need prices by float range. SkinPricer collects them from the markets that segment by float and serves them from [`GET /v1/attribute-prices/latest`](/api-docs/floats) as buckets: one price per float band, per market, with ask, bid, and listing counts. This guide covers how the buckets are built, how to find the one your float falls into, and how to measure the low-float premium.

## How float buckets work

Buckets follow each market's own segmentation rather than an invented common scheme, so bucket widths differ by venue. Every bucket describes its exact bounds in `dimensions.float`, as a half-open range (`minInclusive: true`, `maxInclusive: false`), and never crosses an exterior boundary.

| Market | Float bands |
| --- | --- |
| `buff163` | BUFF's native, non-uniform ranges. For Field-Tested: 0.15 to 0.18, 0.18 to 0.21, 0.21 to 0.24, 0.24 to 0.27, and 0.27 to 0.38. |
| `steamcommunity`, `marketcsgo`, `csfloat`, `dmarket` | Uniform 0.01-wide bins: 0.15 to 0.16, 0.16 to 0.17, and so on, clamped to the exterior. |

The full band table for every exterior lives on the [attribute buckets concept page](/api-docs/attribute-buckets). The practical rule is simple: never parse or compare bucket labels across markets. Compare on `dimensions.float.min` and `dimensions.float.max`.

## Step 1: fetch the float buckets for an item

Scope the request to one item with `marketHashName` (or `canonicalItemId`). Float buckets are returned by default, from every supported market, and the latest read is included from the Developer plan up. Restrict venues with `markets`; any venue you ask for that has no bucket coverage is listed in `sourceGaps` instead of being silently dropped.

**curl**

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

curl -s "https://pricing.skinpricer.com/v1/attribute-prices/latest?marketHashName=AK-47%20%7C%20Redline%20(Field-Tested)&markets=buff163,csfloat" \
  -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 res = await client.attributePrices.latest({
  marketHashName: "AK-47 | Redline (Field-Tested)",
  markets: ["buff163", "csfloat"],
});

for (const item of res.items) {
  console.log(`${item.market}: ${item.buckets.length} float buckets`);
}
```

**Python**

```python
import os

import requests

res = requests.get(
    "https://pricing.skinpricer.com/v1/attribute-prices/latest",
    params={
        "marketHashName": "AK-47 | Redline (Field-Tested)",
        "markets": "buff163,csfloat",
    },
    headers={"Authorization": f"ApiKey {os.environ['SKINPRICER_API_KEY']}"},
    timeout=10,
)
res.raise_for_status()
data = res.json()
print("markets without coverage:", data["sourceGaps"])
```

**Response 200** (`GET /v1/attribute-prices/latest`)

```json
{
  "bucketSchemaVersion": 1,
  "markets": ["buff163", "steamcommunity", "marketcsgo", "csfloat", "dmarket"],
  "currency": "USD",
  "asOf": "2026-06-23T09:18:45.864Z",
  "items": [
    {
      "canonicalItemId": "cmlofa7dh08ww01yo9lrpej3e",
      "marketHashName": "★ Karambit | Doppler (Factory New) - Phase 2",
      "market": "buff163",
      "buckets": [
        {
          "bucketId": "buff163:cmlofa7dh08ww01yo9lrpej3e:tag:446954:float:0-0.01",
          "bucketKey": "tag:446954:float:0-0.01",
          "bucketType": "attribute",
          "attributeType": "tag",
          "attributeTypes": ["tag", "float"],
          "dimensions": {
            "variant": "Phase2",
            "float": { "min": 0, "max": 0.01, "minInclusive": true, "maxInclusive": false },
            "fade": null,
            "pattern": null,
            "paintSeed": null
          },
          "sourceItemId": "44102",
          "sourceBucketId": "buff163:44102:tag446954:f0-0.01",
          "askCents": 197795,
          "avgAskCents": 201340,
          "medianAskCents": 199500,
          "bidCents": 179787,
          "askListingCount": 82,
          "bidOrderCount": null,
          "sourceUpdatedAt": "2026-06-23T09:10:00.000Z",
          "collectedAt": "2026-06-23T09:11:35.446Z"
        },
        {
          "bucketId": "buff163:cmlofa7dh08ww01yo9lrpej3e:tag:446954:float:0.01-0.02",
          "bucketKey": "tag:446954:float:0.01-0.02",
          "bucketType": "attribute",
          "attributeType": "tag",
          "attributeTypes": ["tag", "float"],
          "dimensions": {
            "variant": "Phase2",
            "float": { "min": 0.01, "max": 0.02, "minInclusive": true, "maxInclusive": false },
            "fade": null,
            "pattern": null,
            "paintSeed": null
          },
          "sourceItemId": "44102",
          "sourceBucketId": "buff163:44102:tag446954:f0.01-0.02",
          "askCents": 189676,
          "avgAskCents": 191220,
          "medianAskCents": 190100,
          "bidCents": 179344,
          "askListingCount": 66,
          "bidOrderCount": null,
          "sourceUpdatedAt": "2026-06-23T09:10:00.000Z",
          "collectedAt": "2026-06-23T09:11:35.446Z"
        }
      ]
    }
  ],
  "nextCursor": null,
  "sourceGaps": []
}
```

*The documented response shape. Each bucket carries its own ask, bid, and listing counts, and `dimensions.float` holds the exact band.*

## Step 2: find the bucket your float falls into

Given one skin's float, pick the bucket whose range contains it on each market. Respect the inclusivity flags so a float of exactly 0.18 lands in the 0.18 to 0.21 band, not the 0.15 to 0.18 one.

```ts
import type { AttributePriceBucket } from "@skinpricer/sdk";

/** The float bucket containing `value`, honoring half-open bounds. */
function bucketFor(value: number, buckets: AttributePriceBucket[]) {
  return buckets.find((b) => {
    const r = b.dimensions.float;
    if (!r) return false;
    const aboveMin = r.minInclusive ? value >= r.min : value > r.min;
    const belowMax = r.maxInclusive ? value <= r.max : value < r.max;
    return aboveMin && belowMax;
  });
}

const myFloat = 0.1512;
for (const item of res.items) {
  const bucket = bucketFor(myFloat, item.buckets);
  const ask = bucket?.askCents;
  console.log(item.market, ask == null ? "no listing in this band" : formatUsd(ask));
}
```

## Step 3: measure the low-float premium

The premium for a low float is easiest to read as a ratio: the ask in your band divided by the ask in the item's highest band on the same market. Comparing within one market avoids mixing different band widths and different fee structures. On BUFF, the 0.15 to 0.18 band of a Field-Tested item is the one closest to Minimal Wear, and it is typically where the premium concentrates.

```ts
for (const item of res.items) {
  const priced = item.buckets.filter((b) => b.askCents !== null && b.dimensions.float);
  const top = priced.reduce<AttributePriceBucket | undefined>(
    (hi, b) => (!hi || b.dimensions.float!.min > hi.dimensions.float!.min ? b : hi),
    undefined,
  );
  if (!top?.askCents) continue;

  for (const b of priced) {
    const ratio = b.askCents! / top.askCents;
    console.log(item.market, b.bucketKey, `${((ratio - 1) * 100).toFixed(1)}% vs highest band`);
  }
}
```

*A premium measured on one or two listings is noise. Weight it by `askListingCount`, or skip bands below a minimum count.*

## Step 4: watch one band over time

Each bucket has a stable `bucketId`. Pass one or more of them (`bucketIds` accepts a list) to [attribute price history](/api-docs/attribute-history) to get a `points[]` series with open, high, low, and close asks and the closing bid per interval. History reads require the Pro plan, default to the last 7 days, and accept `10m`, `1h`, or `1d` spacing.

```ts
const lowBand = res.items
  .find((i) => i.market === "buff163")
  ?.buckets.find((b) => b.dimensions.float?.min === 0.15);

if (lowBand) {
  const history = await client.attributePrices.history({
    bucketIds: [lowBand.bucketId],
    granularity: "1d",
    from: new Date(Date.now() - 60 * 24 * 60 * 60 * 1000),
  });
  const points = history.items[0]?.buckets[0]?.points ?? [];
  console.log(points.map((p) => p.closeAskCents));
}
```

**Response 200** (`GET /v1/attribute-prices/history`)

```json
{
  "bucketSchemaVersion": 1,
  "markets": ["buff163", "steamcommunity", "marketcsgo", "csfloat", "dmarket"],
  "currency": "USD",
  "granularity": "10m",
  "items": [
    {
      "canonicalItemId": "cmlofa7dh08ww01yo9lrpej3e",
      "marketHashName": "★ Karambit | Doppler (Factory New) - Phase 2",
      "market": "buff163",
      "buckets": [
        {
          "bucketId": "buff163:cmlofa7dh08ww01yo9lrpej3e:tag:446954:float:0-0.01",
          "bucketKey": "tag:446954:float:0-0.01",
          "bucketType": "attribute",
          "attributeType": "tag",
          "attributeTypes": ["tag", "float"],
          "dimensions": {
            "variant": "Phase2",
            "float": { "min": 0, "max": 0.01, "minInclusive": true, "maxInclusive": false },
            "fade": null,
            "pattern": null,
            "paintSeed": null
          },
          "points": [
            {
              "bucketStart": "2026-06-16T14:40:00.000Z",
              "openAskCents": 192390,
              "highAskCents": 192390,
              "lowAskCents": 192390,
              "closeAskCents": 192390,
              "avgAskCents": 192390,
              "closeBidCents": 179367,
              "askListingCount": 87,
              "bidOrderCount": null,
              "firstObservedAt": "2026-06-16T14:41:02.190Z",
              "lastObservedAt": "2026-06-16T14:41:04.342Z"
            },
            {
              "bucketStart": "2026-06-16T14:50:00.000Z",
              "openAskCents": 192390,
              "highAskCents": 192390,
              "lowAskCents": 192390,
              "closeAskCents": 192390,
              "avgAskCents": 192390,
              "closeBidCents": 179367,
              "askListingCount": 87,
              "bidOrderCount": null,
              "firstObservedAt": "2026-06-16T14:51:03.475Z",
              "lastObservedAt": "2026-06-16T14:51:12.491Z"
            },
            {
              "bucketStart": "2026-06-16T15:00:00.000Z",
              "openAskCents": 192410,
              "highAskCents": 192410,
              "lowAskCents": 192410,
              "closeAskCents": 192410,
              "avgAskCents": 192410,
              "closeBidCents": 179385,
              "askListingCount": 87,
              "bidOrderCount": null,
              "firstObservedAt": "2026-06-16T15:00:49.830Z",
              "lastObservedAt": "2026-06-16T15:00:49.830Z"
            }
          ]
        }
      ]
    }
  ],
  "sourceGaps": []
}
```

## Pitfalls that skew float prices

- Bands differ per market, so a BUFF 0.15 to 0.18 price and a Steam 0.15 to 0.16 price are not the same thing. Compare markets only on overlapping ranges.
- Not every market reports buy orders per float band, so `bidCents` and `bidOrderCount` are often `null` outside BUFF. That means no band-level bid was observed, not a bid of zero.
- A band's ask is the cheapest listing inside that band. On thin bands it can be a single listing, so check `askListingCount` before quoting it.
- Without an item scope the endpoint returns a paginated snapshot of every item. Follow `nextCursor` until it is `null` (the SDK's `latestEach` does this for you).
- Fade and pattern buckets are omitted by default. Add `attributes=float,fade,tag` for fade percentages (such as 90 to 93) and phase or pattern tags.

> **Buckets describe bands, not your exact skin:** A bucket price is what the market charges for any float in that band. Stickers, pattern, and a float right at a band edge can all move the price of one specific skin. For the individual listings behind a band, read [per-listing data](/resources/cs2-listing-float-paint-seed-stickers).

## When to reach for a different endpoint

For Doppler and Gamma Doppler, float bands sit inside each phase; the [phase pricing guide](/resources/cs2-doppler-phase-prices) covers that case. If BUFF is the only venue you need, the [BUFF163 guide](/resources/buff163-prices-and-history) uses the market-scoped endpoints. And if you need each item's possible float range before you price anything, sync it from the item schema as shown in [syncing the CS2 item catalog](/resources/sync-cs2-item-catalog).

## Endpoints used

- [GET /v1/attribute-prices/latest](/api-docs/floats.md)
- [How attribute & float buckets are built](/api-docs/attribute-buckets.md)
- [GET /v1/attribute-prices/history](/api-docs/attribute-history.md)
- [GET /v1/markets/buff163/latest](/api-docs/buff163.md)

## Related guides

- [How to get CS2 Doppler phase prices, from Phase 1 to Emerald](/resources/cs2-doppler-phase-prices.md)
- [How to get float, paint seed, and sticker data for live CS2 listings](/resources/cs2-listing-float-paint-seed-stickers.md)
- [How to get BUFF163 prices, float buckets, and history in USD](/resources/buff163-prices-and-history.md)
- [How to sync the full CS2 item catalog with float ranges and images](/resources/sync-cs2-item-catalog.md)
