How to get float, paint seed, and sticker data for live CS2 listings
Get per-listing CS2 data: float value, paint seed, paint index, and stickers for live listings across marketplaces, with runnable curl and TypeScript.
On this page
Aggregated prices answer "what does this item cost". They cannot answer "what does this particular skin cost", because two listings of the same market hash name can differ in float, pattern, and applied stickers, and each of those moves the price. For that you need the individual listings, one row per skin for sale, with its attributes attached.
GET /v1/pricing/:marketHashName/listings returns exactly that: a sample of live listings across markets, each with its price, float value, paint seed, paint index, stickers, and StatTrak flag, plus metadata about which markets exposed floats. It powers float-versus-price scatter plots, sticker-craft searches, and pattern hunting.
What each listing carries#
| Field | Meaning |
|---|---|
market / listingId | The venue and its own listing id. listingId is null on aggregate fallback rows (see below). |
price | The listing price in integer USD cents. |
floatValue | The wear value from 0 to 1, or null when the market does not publish it. |
paintSeed | The pattern index that decides the texture placement, or null. |
paintIndex | The finish catalog index, which also identifies Doppler phases on knives, or null. |
stickers | Applied stickers as { name, slot, wear } objects. An empty array when none are applied or reported. wear is the sticker's scratch wear, 0 (new) to 1 (fully scratched), and is omitted when the market does not report it. Treat a missing wear as unknown, not 0. |
isStatTrak | Whether the listing is StatTrak. |
inspectLink / fetchedAt | An inspect reference when available, and when the listing was last fetched. |
Step 1: request the listings#
Put the URL-encoded market hash name in the path. limit controls the sample size (1 to 2000, default 500), and market (or its alias markets) restricts the venues with a comma-separated list. The endpoint is included from the Developer plan up.
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)/listings?limit=200" \
-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 res = await client.pricing.listings("AK-47 | Redline (Field-Tested)", {
limit: 200,
});
console.log(`${res.sampledListings} of ${res.totalListings} listings, float coverage: ${res.floatCoverage.coverage}`);
for (const l of res.listings.slice(0, 5)) {
console.log(l.market, formatUsd(l.price), l.floatValue ?? "no float", l.paintSeed ?? "no seed");
}import os
from urllib.parse import quote
import requests
name = "AK-47 | Redline (Field-Tested)"
res = requests.get(
f"https://pricing.skinpricer.com/v1/pricing/{quote(name, safe='')}/listings",
params={"limit": 200},
headers={"Authorization": f"ApiKey {os.environ['SKINPRICER_API_KEY']}"},
timeout=10,
)
res.raise_for_status()
data = res.json()
with_float = [l for l in data["listings"] if l["floatValue"] is not None]
print(f"{len(with_float)} of {data['sampledListings']} sampled listings have a float"){
"marketHashName": "AK-47 | Redline (Field-Tested)",
"canonicalItemId": "cmlofczf90qj401vsd80dskd1",
"totalListings": 22022,
"sampledListings": 2,
"floatCoverage": {
"coverage": "partial",
"sampledListings": 2,
"listingsWithFloat": 2,
"marketsWithFloat": [
"avanmarket"
],
"marketsWithoutFloat": [
"buff163",
"csfloat",
"cstrade",
"dmarket",
"itrade",
"lis-skins",
"lootfarm",
"mannco-store",
"marketcsgo",
"skindeck",
"skinport",
"steamcommunity",
"swapgg",
"tradeit-store",
"tradeit-trade",
"waxpeer",
"whitemarket"
]
},
"floatSummary": {
"observed": 0.15027404,
"itemMin": 0.15,
"itemMax": 0.38,
"observedSource": {
"market": "avanmarket",
"price": 9404,
"fetchedAt": "2026-09-25T11:25:44.891Z",
"isStale": false
}
},
"listings": [
{
"listingId": "listing:5698b064-d92a-4b7f-8c5f-4aa014d1400e",
"market": "avanmarket",
"price": 9484,
"currency": "USD",
"originalPriceCents": 9484,
"originalCurrency": "USD",
"floatValue": 0.15005141,
"paintSeed": null,
"paintIndex": null,
"inspectLink": null,
"stickers": [],
"isStatTrak": false,
"fetchedAt": "2026-09-25T11:25:44.891Z",
"isStale": false
},
{
"listingId": "listing:e40c11f4-73f7-4d15-89e4-765e3ee14253",
"market": "avanmarket",
"price": 9404,
"currency": "USD",
"originalPriceCents": 9404,
"originalCurrency": "USD",
"floatValue": 0.15027404,
"paintSeed": null,
"paintIndex": null,
"inspectLink": null,
"stickers": [
{
"name": "Sticker | device | Cologne 2016",
"slot": 0
},
{
"name": "Sticker | Astralis (Holo) | Cologne 2016",
"slot": 1
},
{
"name": "Sticker | device (Foil) | Cologne 2016",
"slot": 2
}
],
"isStatTrak": false,
"fetchedAt": "2026-09-25T11:25:44.891Z",
"isStale": false
}
],
"calculatedAt": "2026-09-25T11:33:18.805Z"
}floatCoverage says which markets contributed floats to this sample; floatSummary places the observed float inside the item's possible range.Fetch live AK-47 | Redline (Field-Tested) listings right now, in your browser.
Step 2: know what the sample is#
The response is a sample of up to limit listings (sampledListings) out of all active listings (totalListings), drawn from listings seen in the last 24 hours. It is ordered for attribute work: listings with a known float come first, lowest float first, and price breaks ties. That makes it the right input for float and pattern analysis, and the wrong one for finding the cheapest listing, which is what the best ask is for.
floatCoverage.coverageiscomplete,partial, ornone.marketsWithFloatlists the venues that contributed a float in this sample, andmarketsWithoutFloatlists the active venues that did not.floatSummary.observedis the float of the cheapest float-bearing listing in the sample, withobservedSourcenaming its market, price, and fetch time.itemMinanditemMaxare the item's possible float range, already clamped to its exterior.- When no individual listings are available, the endpoint falls back to one latest row per market, with
listingId: nulland no attributes. Treat those as prices, not as skins.
Step 3: filter by float, pattern, or stickers#
With the sample in hand, the filters are ordinary code. The published SDK types stickers loosely, so narrow each entry before reading it. The example below finds listings under a float ceiling, a set of paint seeds you care about, and any listing carrying a given sticker, then prints that listing's stickers with a missing wear shown as unknown.
interface Sticker {
name: string;
slot: number;
wear?: number | null; // 0 (new) to 1 (fully scratched); omitted when unknown
}
function isSticker(value: unknown): value is Sticker {
return typeof value === "object" && value !== null && "name" in value && "slot" in value;
}
// A missing wear is unknown, never 0% scratched.
function stickerWear(s: Sticker): string {
return s.wear == null ? "unknown" : `${Math.round(s.wear * 100)}%`;
}
const lowFloat = res.listings.filter((l) => l.floatValue !== null && l.floatValue < 0.16);
const wantedSeeds = new Set([661, 670]);
const patterns = res.listings.filter((l) => l.paintSeed !== null && wantedSeeds.has(l.paintSeed));
const withCrown = res.listings.filter((l) =>
l.stickers.filter(isSticker).some((s) => s.name.includes("Crown (Foil)")),
);
console.log(lowFloat.length, "low floats,", patterns.length, "pattern matches,", withCrown.length, "with Crown (Foil)");
for (const s of withCrown[0]?.stickers.filter(isSticker) ?? []) {
console.log(`slot ${s.slot}: ${s.name}, wear ${stickerWear(s)}`);
}Coverage varies by market#
Only some venues expose per-listing attributes, and coverage changes as markets change their feeds. Read floatCoverage on every response rather than hard-coding a list. If you need a float-level price but the listing sample for an item is thin, the market-level float buckets are often better populated: the float range guide shows how to read them.
Rust has no float, pattern, or sticker semantics. The game-scoped /v2 listings route returns the same shape with those fields always null or empty; see Games: CS2 & Rust.
When to reach for a different endpoint#
For the price of a float band rather than individual skins, use attribute prices. For Doppler and Gamma Doppler, the phase pricing guide prices each phase separately. And for the current best price across every venue, regardless of attributes, use the live pricing snapshot.
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
- Floats & attributesIntermediate
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.
GET /v1/attribute-prices/latestGET /v1/attribute-prices/history6 min read - Floats & attributesIntermediate
How to get CS2 Doppler phase prices, from Phase 1 to Emerald
Price CS2 Doppler and Gamma Doppler by phase: Phase 1 to 4, Ruby, Sapphire, Black Pearl, and Emerald, with live buckets and history. Runnable code.
GET /v1/schema/items/:idOrNameGET /v1/nbbo6 min read - Prices & quotesBeginner
How to get live CS2 skin prices from every marketplace
Pull live CS2 skin prices from every major marketplace in one call: per-market asks, bids, and aggregate stats in USD cents, with runnable curl and TypeScript.
GET /v1/pricing/:marketHashNameGET /v1/items6 min read