REST · JSON · CS2 + Rust

Steam Data API

A fast, fully managed REST API for Counter-Strike 2 and Rust market items - current prices, daily price history, third-party marketplace prices, collections and metadata. Built as a drop-in alternative to expensive third-party data subscriptions.

Live prices

Latest sell, median, buy-order and 24h volume per item, refreshed continuously from the Steam Community Market.

Daily history

Steam's daily median-sale price is the long-term backbone; every third-party market is served as daily lowest ask. One consistent metric per source.

13 marketplaces

Lowest live price & quantity across Steam, CSFloat, Skinport, WhiteMarket, DMarket, Waxpeer, Lis-Skins, SkinBaron, HaloSkins, Mannco & the Chinese markets Buff163, YouPin, C5Game - with the computed best price, cheapest source and spread.

Rich metadata

Wear, StatTrak™, souvenir, rarity, type, weapon and official Steam collection tags.

Market coverage. CS2 is priced from 12 markets - Steam, CSFloat, Skinport, WhiteMarket, DMarket, Waxpeer, Lis-Skins, SkinBaron, HaloSkins, plus the three biggest Chinese markets Buff163, YouPin and C5Game (converted to USD from CNY). Rust from 5 - Steam, Skinport, DMarket, Waxpeer and Lis-Skins (CSFloat and WhiteMarket don't list Rust). Every price is normalised to integer cents and compared on the same request - the Chinese markets count toward best/real like any other.

Quick start

Every request needs an API key. Grab one from the dashboard, then send it as a Bearer token:

cURL
curl "https://api.example.com/api/v1/items/AK-47%20%7C%20Redline%20(Field-Tested)?game=cs2" \
  -H "Authorization: Bearer sdk_your_api_key_here"

Authentication

All data endpoints require an API key. Pass it in the Authorization header as a Bearer token. Keys look like sdk_xxxxxxxx… and are shown in full only once at creation time.

Header
Authorization: Bearer sdk_3f9a1c7b2e4d…
Dashboard users can alternatively authenticate with a session JWT (sent as a Bearer token or the sdk_session cookie). Machine-to-machine integrations should always use an sdk_ API key.
Send a User-Agent. The API sits behind Cloudflare, which blocks requests with missing or bare-bones client signatures before they reach us (typically as Error 1010). Default python-urllib is a known casualty. Set a descriptive header and you'll never see it: User-Agent: your-app/1.0 (you@example.com). curl and python-requests defaults are generally fine.

Requests without a valid key receive 401 Unauthorized. Every 401 carries a reason field so you can tell the cases apart without guessing: missing (no credentials sent), scheme (not a Bearer token), api_key (the key is unknown, revoked or regenerated) and session (dashboard session expired). Regenerating a key in the dashboard invalidates the previous one - the old key stops working within about a minute, so update any running integration at the same time.

Base URL & versioning

All endpoints are served under a versioned prefix. The base URL of this instance is:

Base URL
https://api.example.com/api/v1

Each endpoint below lists its parameters with a copy-paste curl example and a sample JSON response.

Rate limits & quotas

Limits are per endpoint group and scale with your plan: every group has its own per-minute rate limit, daily cap and monthly quota, tracked per API key. There is no shared pool - maxing out one endpoint never blocks another. The headline request number you see on a plan card is the Item-lookups group; other groups (notably Price history) carry their own, different caps - check the table below before planning a bulk pull. You can watch your live usage for every endpoint group on the dashboard.

Exact numbers per plan - rendered live from /api/v1/plans (the same values the API enforces with):

Plan:

Loading plan limits…
Planning a bulk archive? Per-item history pulls bill the Price history group, whose daily cap is separate from (and on most plans lower than) Item lookups - a full-catalog history backfill may need to span more than one UTC day. If you have a one-off archival run that doesn't fit the caps, contact us and we'll work something out.

Exceeding a group's per-minute limit returns 429 rate_limited (with x-ratelimit-* headers); its daily cap returns 429 daily_quota_exceeded and its monthly quota 429 quota_exceeded (both carry an x-quota-group header naming the group). Some endpoints are plan-gated - Inventory needs Pro+, Price history & Marketplaces need Scale+ - and a call your plan doesn't include returns 403 plan_forbidden. The bulk endpoints count as one request each, however many items you pass.

Each endpoint below carries a billing pill showing what one call costs. A solid 1× group is always billed; a dashed +1× group?param is an add-on billed only when you pass that parameter - e.g. ?markets=1 adds a Marketplaces request on top of the base call, and ?fresh=1 adds a second Inventory request. The groups are Item lookups, Bulk prices, Marketplaces, Price history, Collections and Inventory - each a separate quota bucket, so one never eats another's.

During maintenance an endpoint may return 503 endpoint_disabled - the dashboard's API Status page shows what's currently live.

Errors

Errors use standard HTTP status codes and a consistent JSON body:

JSON
{
  "error": "bad_request",
  "message": "Human-readable explanation"
}
StatusCodeMeaning
400bad_requestInvalid query/body parameters (see issues).
401unauthorizedMissing or invalid API key - see reason: missing, scheme, api_key or session.
403forbiddenAuthenticated but lacking the required role.
403plan_forbiddenEndpoint not included in your plan.
403inventory_privateThe requested Steam inventory (or profile) is private.
404not_foundItem or resource does not exist.
429rate_limitedToo many requests this minute.
429quota_exceededMonthly request quota reached.
503endpoint_disabledEndpoint temporarily disabled for maintenance.
500internal_errorUnexpected server error.

Money & currency

All monetary values are integer minor units (cents) to avoid floating-point drift - a priceLatest of 1234 means $12.34. Each response carries an explicit currency field (default USD). Price filters in query strings (e.g. price_min) accept major units (dollars) for convenience.

Multi-currency output

Add ?currency=EUR (or any of 30+ supported currencies) to any item or price endpoint to convert every monetary value on the fly using daily ECB reference rates. The response's currency field reflects the conversion. Unsupported codes return 400 bad_request with the supported list.

GET /api/v1/currencies (no auth required) lists every accepted code plus the age of the loaded rates - handy for populating a currency picker:

JSON
{ "base": "USD", "currencies": ["AUD", "BRL", "CAD", "…", "USD", "ZAR"], "ratesUpdatedAgoSeconds": 7223 }

Price fields

Every endpoint that returns prices uses the same field names with the same meaning. Learn them once here - the endpoint pages just tell you which subset they return.

FieldMeaning
prices.best · bestSourceThe lowest buyable price anywhere - Steam vs every third-party market - and which market has it. Steam prices at its ~$1,800 listing cap are excluded (not a real buy price). Start here if you just want "what does it cost".
prices.latestSteam's current lowest ask (cheapest listing on the Steam Community Market).
prices.latestSell · medianSteam's most recent sale / official median sale price.
prices.buyorderHighest open Steam buy order - what you could instantly sell for on Steam.
prices.real · realMarketThe lowest third-party price right now - the price you can actually buy at - and which marketplace has it, across every market including the Chinese ones.
prices.realMedianMedian of the current lowest prices across the third-party marketplaces - a robust fair value that one outlier market can't skew. Inventory responses value items at this.
sold24hSteam sales in the last 24 hours - the liquidity signal.
variants[]Doppler / Gamma Doppler only: per-phase price + quantity per marketplace (Ruby, Sapphire, Black Pearl, Emerald, Phase 1-4). Phases share one market hash name but trade very differently.
All prices are integer cents in the response's currency. A price is null when that market has no current listing - not zero.
Trade-up metadata. Weapon, knife and glove skins carry minFloat, maxFloat, paintIndex and defIndex from the game files (refreshed daily). Two deliberate nulls: Doppler/Gamma Doppler base items have paintIndex: null - one name maps to seven per-phase paint indexes, so no single value is correct (phase prices live in variants) - and non-skin items (stickers, cases, agents…) have no float range. There is no separate quality value: StatTrak™/Souvenir/★ status is expressed by isStattrak, isSouvenir and the prefix in the name.

Which endpoint do I need?

I want…Call
One item, full detail (metadata, all prices, Doppler phases)GET /items/:name
Every current price for a whole game, one callGET /items/all
Prices for my list of items (≤500)POST /items/prices
Where an item is cheapest right now, per marketplaceGET /items/:name/markets
The cheapest market for my list (≤100)POST /items/markets
Price over time (Steam median, per-market lowest ask, per-phase)GET /items/:name/history
History for my list (≤100)POST /items/history

Single item

GET/api/v1/items/:marketHashName1× Item lookups+1× Marketplaces?markets=1API key

Everything we know about one item, by its (URL-encoded) market hash name: full metadata, all price fields, volume - and for Dopplers, the per-phase variants. For the live per-marketplace breakdown, call Marketplace prices - or embed the same rows right here with ?markets=1; for series over time, Price history.

ParamInDescription
marketHashName requiredpathURL-encoded market hash name, e.g. AK-47%20%7C%20Redline%20(Field-Tested).
gamequeryOptional game slug to disambiguate.
currencyqueryOptional output currency (e.g. EUR).
marketsquerytrue/1 embeds the markets array - the latest price & stock per third-party marketplace, same rows as Marketplace prices. Requires Marketplaces access (Scale+) and bills one Marketplaces request.
formatqueryjson (default), csv or xml. gzip is automatic via Accept-Encoding.
Request
curl "https://api.example.com/api/v1/items/AK-47%20%7C%20Redline%20(Field-Tested)?game=cs2&markets=1" \
  -H "Authorization: Bearer sdk_…"
200 Response (truncated)
{
  "marketHashName": "AK-47 | Redline (Field-Tested)",
  "currency": "USD",
  "prices": {
    "best": 1690, "bestSource": "csfloat",   // lowest across every market + who has it
    "latest": 1899, "median": 1925, "buyorder": 1810,  // Steam ask / median sale / highest buy order
    "real": 1690, "realMarket": "csfloat", "realMedian": 1745  // lowest & median across 3rd-party
  },
  "volume": { "sold24h": 412, "offerVolume": 2204, "buyorderVolume": 331 },
  // item icon on Steam's CDN, always included
  "image": { "url": "https://community.akamai.steamstatic.com/economy/image/i0CoZ81Ui0m…/360fx360f" },
  // only with ?markets=1 - latest price & stock per third-party marketplace (icon = the marketplace's favicon)
  "markets": [
    { "market": "csfloat", "icon": "https://steamdataapi.com/img/markets/csfloat-c.png", "price": 1690, "quantity": 41, "capturedAt": "2026-07-21T09:12:00.000Z" },
    { "market": "buff163", "icon": "https://steamdataapi.com/img/markets/buff163-c.png", "price": 1652, "quantity": 230, "capturedAt": "2026-07-21T09:10:00.000Z" }
  ]
}
For Doppler / Gamma Doppler items - which share one market hash name but trade very differently by phase - the response adds a variants array with the per-phase price + quantity (Ruby, Sapphire, Black Pearl, Phase 1-4, Emerald), e.g. "variants": [{ "phase": "Phase 4", "market": "dmarket", "icon": "https://steamdataapi.com/img/markets/dmarket-c.png", "price": 125300, "quantity": 2 }, …]. Inventory responses value each Doppler at its actual phase.
A 404 not_found is returned if the item is not in the catalog.

All items & prices

GET/api/v1/items/all1× Bulk prices+1× Marketplaces?markets=1API key

The price sheet: every item for a game with its current prices, in one response - no pagination. Poll this to mirror all prices locally instead of paging through the catalog. It's deliberately lean - name + the price fields + sold24h - because you poll it often; add ?images=1 for item icons, and metadata that rarely changes (rarity, floats, collections) lives on the per-item Single item lookup. Served from a ~60 s server-side cache (cachedAt is the snapshot time). ~4 MB per game. Metered as Bulk: one call counts as a single request against your Bulk-prices quota, however many items it returns.

ParamInDescription
gamequerycs2 or rust - omit for both games.
currencyqueryOptional output currency (e.g. EUR).
marketsquerytrue/1 adds a markets array to every row - the latest price & stock on each third-party marketplace, from that market's most recent sync. Requires Marketplaces access (Scale+), bills one Marketplaces request on top of the call, and roughly quadruples the payload.
imagesquerytrue/1 adds an image object to every row (see below). No extra billing - it's catalog metadata - but icon URLs are long, so the response roughly doubles, from ~1.3 MB to ~3 MB gzipped.
variantsquerytrue/1 adds a variants array to rows that have phases (Doppler / Gamma Doppler knives): per phase, the cross-market best + bestMarket. Combine with markets=1 and each phase also carries its own per-marketplace markets rows; combine with images=1 and each phase carries its own image - the Ruby render, not the blended Doppler icon. No extra billing on its own.
Phase prices. Dopplers share one marketHashName on Steam, but each phase trades very differently - variants carries the phase-aware prices from the marketplaces that expose the phase per listing. variants appears only on rows that have phases (~1,500 Doppler/Gamma knives of the ~30k catalog); rows without phases are byte-identical with or without variants=1.
Coverage baseline (marketCoverage). With ?markets=1 the response carries a top-level marketCoverage object - per marketplace, how many rows this response embeds and their newest capturedAt. rows is exact: it counts the same rows you'll find in the markets arrays below it - same game filter, same outlier filter - so sum(items.markets where market=X) always equals marketCoverage[X].rows. Use it as a completeness check, not just staleness: a marketplace mid-refresh (DMarket paginates for several minutes; the others land in one batch) or mid-outage can be fresh yet partial, and comparing rows against your previous pull catches that where capturedAt alone cannot.
Item images. We have an icon for 99% of the catalog. image.url is the item's icon on Steam's own CDN - an absolute URL you can drop straight into an <img src>, served globally by Valve. It's null only for the handful of rare items (mostly knives surfaced by third-party feeds) that Steam has never listed an image for.
Fetch icons once, not every poll: an item's image never changes, so store them on first sight and keep polling the sheet without ?images=1 - that keeps your recurring transfer at ~1.3 MB instead of ~3 MB per call.
Request
curl "https://api.example.com/api/v1/items/all?game=cs2" \
  -H "Authorization: Bearer sdk_…"
200 Response
{
  "currency": "USD",
  "count": 35163,
  "cachedAt": "2026-07-16T09:00:00Z",
  // only with ?markets=1 - per-marketplace completeness baseline (see note above)
  "marketCoverage": {
    "dmarket": { "rows": 18204, "newestCapturedAt": "2026-07-16T08:58:41Z" },
    "skinport": { "rows": 21730, "newestCapturedAt": "2026-07-16T08:57:12Z" }
  },
  "data": [
    {
      "marketHashName": "AK-47 | Redline (Field-Tested)", "game": "cs2",
      // only with ?images=1 - the item's icon on Steam's CDN
      "image": { "url": "https://community.akamai.steamstatic.com/economy/image/i0CoZ81Ui0m…/360fx360f" },
      "prices": {
        "best": 2519, "bestSource": "skinport",
        "latest": 4225, "median": 4074, "buyorder": 4172,
        "real": 2519, "realMarket": "skinport", "realMedian": 3021
      },
      "sold24h": 76, "priceUpdatedAt": "2026-07-16T09:00:00Z",
      // only with ?markets=1 - latest price & stock per third-party marketplace (icon = favicon URL)
      "markets": [
        { "market": "skinport", "icon": "https://steamdataapi.com/img/markets/skinport-c.png", "price": 2519, "quantity": 18, "capturedAt": "2026-07-16T08:57:00Z" },
        { "market": "buff163", "icon": "https://steamdataapi.com/img/markets/buff163-c.png", "price": 2602, "quantity": 151, "capturedAt": "2026-07-16T08:55:00Z" }
      ]
    }
  ]
}

Bulk prices

POST/api/v1/items/prices1× Bulk prices+1× Marketplacesmarkets:trueAPI key

Look up prices for up to 500 items in a single request - built for trading bots that would otherwise make hundreds of round-trips. Counts as one request against your quota. Each match returns Steam latest / median / min / buyorder plus the computed real (lowest third-party) and realMedian prices. For the per-marketplace breakdown of many items, use Bulk marketplace prices.

FieldInDescription
names requiredbodyArray of market hash names (max 500).
gamebodyGame slug to disambiguate (e.g. cs2).
currencybodyOptional output currency (e.g. EUR).
marketsbodytrue adds a markets array to every matched item - the latest price & stock on each third-party marketplace. Requires Marketplaces access (Scale+) and bills one Marketplaces request on top of the call.
imagesbodytrue adds an image object (url = the item's icon on Steam's CDN) to every matched item. No extra billing.
Request
curl -X POST "https://api.example.com/api/v1/items/prices" \
  -H "Authorization: Bearer sdk_…" \
  -H "Content-Type: application/json" \
  -d '{ "game": "cs2", "currency": "EUR", "markets": true, "names": ["AK-47 | Redline (Field-Tested)", "Glock-18 | Fade (Factory New)"] }'
200 Response
{
  "currency": "EUR",
  "requested": 2, "matched": 1,
  "missing": [ "Glock-18 | Fade (Factory New)" ],
  "data": [
    {
      "marketHashName": "AK-47 | Redline (Field-Tested)", "found": true,
      // only with "images": true
      "image": { "url": "https://community.akamai.steamstatic.com/economy/image/i0CoZ81Ui0m…/360fx360f" },
      "prices": { "latest": 1745, "median": 1769, "min": 1690, "real": 1698, "realMedian": 1712, "buyorder": 1664 },
      "sold24h": 412, "priceUpdatedAt": "2026-07-12T09:00:00Z",
      // only with "markets": true - latest price & stock per third-party marketplace (icon = favicon URL)
      "markets": [
        { "market": "csfloat", "icon": "https://steamdataapi.com/img/markets/csfloat-c.png", "price": 1698, "quantity": 41, "capturedAt": "2026-07-12T08:57:00Z" },
        { "market": "buff163", "icon": "https://steamdataapi.com/img/markets/buff163-c.png", "price": 1655, "quantity": 230, "capturedAt": "2026-07-12T08:55:00Z" }
      ]
    },
    { "marketHashName": "Glock-18 | Fade (Factory New)", "found": false }
  ]
}

Marketplace prices

GET/api/v1/items/:marketHashName/markets1× MarketplacesAPI key

Where is this item cheapest right now? Current lowest price and quantity for sale on every third-party marketplace we track (CSFloat, Skinport, WhiteMarket, DMarket, Waxpeer, Lis-Skins, SkinBaron, HaloSkins, plus the Chinese markets Buff163, YouPin, C5Game - converted to USD from CNY), plus the computed best price, cheapest market and spread (worst minus best - the arbitrage gap). Current prices only: for these series over time, call Price history with source=markets.

Troll-listing filter. A marketplace whose only ask sits absurdly above the item's cross-market floor (think a $10,000 listing on a $5 item) is excluded from the rows, the spread and all aggregates (real/realMedian/value) - everywhere, including history series and inventory valuations - rather than shown as if it were a real price. Souvenir and StatTrak™ items are additionally judged against their plain sibling of the same wear: an ask above 30× the sibling's price is treated as a troll listing on any marketplace, consensus or not. Likewise across exteriors: a worse wear asking more than 15× the item's most expensive better wear is excluded. Doppler / Gamma Doppler phase prices are judged the same way - against the item's blended price (50×) and the same phase on its better wears (15×).
ParamInDescription
marketHashName requiredpathURL-encoded market hash name.
gamequeryOptional game slug.
currencyqueryOptional output currency (e.g. EUR).
formatqueryjson (default), csv or xml. gzip is automatic via Accept-Encoding.
Request
curl "https://api.example.com/api/v1/items/AK-47%20%7C%20Redline%20(Field-Tested)/markets?game=cs2" \
  -H "Authorization: Bearer sdk_…"
200 Response
{
  "currency": "USD",
  "best": { "market": "csfloat", "price": 1690 },
  "spread": 122,
  // icon = the marketplace's favicon (absolute URL) - render it straight from the response
  "markets": [
    { "market": "csfloat",     "icon": "https://steamdataapi.com/img/markets/csfloat-c.png",     "price": 1690, "quantity": 210, "currency": "USD", "capturedAt": "2026-07-12T09:00:00Z" },
    { "market": "skinport",    "icon": "https://steamdataapi.com/img/markets/skinport-c.png",    "price": 1750, "quantity": 63,  "currency": "USD", "capturedAt": "2026-07-12T09:00:00Z" },
    { "market": "whitemarket", "icon": "https://steamdataapi.com/img/markets/whitemarket-c.png", "price": 1772, "quantity": 34,  "currency": "USD", "capturedAt": "2026-07-12T08:45:00Z" },
    { "market": "dmarket",     "icon": "https://steamdataapi.com/img/markets/dmarket-c.png",     "price": 1799, "quantity": 41,  "currency": "USD", "capturedAt": "2026-07-12T08:30:00Z" },
    { "market": "waxpeer",     "icon": "https://steamdataapi.com/img/markets/waxpeer-c.png",     "price": 1812, "quantity": 28,  "currency": "USD", "capturedAt": "2026-07-12T09:00:00Z" },
    { "market": "lisskins",    "icon": "https://steamdataapi.com/img/markets/lisskins-c.png",    "price": 1685, "quantity": 57,  "currency": "USD", "capturedAt": "2026-07-12T09:00:00Z" },
    { "market": "skinbaron",   "icon": "https://steamdataapi.com/img/markets/skinbaron-c.png",   "price": 1741, "quantity": 22,  "currency": "USD", "capturedAt": "2026-07-12T09:00:00Z" },
    { "market": "haloskins",   "icon": "https://steamdataapi.com/img/markets/haloskins-c.png",   "price": 1738, "quantity": 96,  "currency": "USD", "capturedAt": "2026-07-12T09:00:00Z" }
  ]
}

Bulk marketplace prices

POST/api/v1/items/markets1× MarketplacesAPI key

The same per-marketplace breakdown - best price, cheapest market and spread - for up to 100 items in one request. Fans out to every market per item, so it's capped lower than Bulk prices (500). Counts as one request against your quota. Current prices only; use Bulk price history for the daily series.

FieldInDescription
names requiredbodyArray of market hash names (max 100).
gamebodyGame slug to disambiguate (e.g. cs2).
currencyqueryOptional output currency (e.g. EUR).
Request
curl -X POST "https://api.example.com/api/v1/items/markets" \
  -H "Authorization: Bearer sdk_…" \
  -H "Content-Type: application/json" \
  -d '{ "game": "cs2", "names": ["AK-47 | Redline (Field-Tested)", "AWP | Asiimov (Field-Tested)"] }'
200 Response
{
  "currency": "USD",
  "requested": 2, "matched": 1,
  "missing": [ "AWP | Asiimov (Field-Tested)" ],
  "data": [
    {
      "marketHashName": "AK-47 | Redline (Field-Tested)", "found": true,
      "best": { "market": "skinport", "price": 2519 }, "spread": 624,
      "markets": [
        { "market": "skinport", "icon": "https://steamdataapi.com/img/markets/skinport-c.png", "price": 2519, "quantity": 77,   "currency": "USD", "capturedAt": "2026-07-16T09:00:00Z" },
        { "market": "csfloat",  "icon": "https://steamdataapi.com/img/markets/csfloat-c.png",  "price": 2843, "quantity": 3358, "currency": "USD", "capturedAt": "2026-07-16T09:00:00Z" }
      ]
    }
  ]
}

Price history

GET/api/v1/items/:marketHashName/history1× Price historyAPI key

Every time series for an item lives on this one endpoint - source picks which. Points are daily, ordered oldest to newest.

source=You getReaches back
steam defaultSteam median-sale price over time (official median, self-built where absent). Points: { date, price, sold }. This is the long-term backbone.up to 2013
marketsDaily ask on every third-party marketplace (CSFloat, Skinport, WhiteMarket, DMarket, Waxpeer, Lis-Skins, SkinBaron, HaloSkins, Buff163, YouPin, C5Game) plus the Steam ask - one series per market: { date, price, quantity }. Choose the daily value with metric= close (last ask of the day - the default), low (day’s cheapest) or avg (mean of the day’s asks).accrues daily
phasesDoppler / Gamma items: daily price + ask volume per phase, nested phase -> marketplace.accrues daily
ParamInDescription
marketHashName requiredpathURL-encoded market hash name.
sourcequerySee table above; default steam.
daysqueryLast N days (1-365) - or use from · to ISO dates for an exact window.
marketquerymarkets/phases only: narrow to one marketplace, e.g. skinport.
phasequeryphases only: narrow to one phase, e.g. Emerald.
metricquerymarkets only: which daily value - close (last ask of the day, default), low (day’s lowest ask) or avg (mean of the day’s asks). low/avg fall back to close for older days that predate this metric.
game · currencyqueryOptional game slug / output currency.
formatqueryjson (default), csv or xml. gzip is automatic via Accept-Encoding.
Request
# metric=low -> the day's cheapest ask · swap for close (default) or avg
curl "https://api.example.com/api/v1/items/AK-47%20%7C%20Redline%20(Field-Tested)/history?source=markets&days=30&metric=low" \
  -H "Authorization: Bearer sdk_…"

?source=steam - Steam's daily median-sale series (sold = sales that day):

200 Response
{
  "currency": "USD", "source": "steam",
  "data": [
    { "date": "2026-07-06", "price": 4191, "sold": 89 }
  ]
}

?source=markets - one series per market (defaults to the daily close; add &metric=low or &metric=avg for the day’s low / average):

200 Response
{
  "currency": "USD", "source": "markets", "metric": "close",
  "markets": {
    "steam":    [ { "date": "2026-07-15", "price": 4225, "quantity": 1125 } ],
    "skinport": [ { "date": "2026-07-15", "price": 2519, "quantity": 77 } ],
    "csfloat":  [ { "date": "2026-07-15", "price": 2843, "quantity": 3358 } ]
  }
}

?source=phases - Doppler phases, nested phase -> marketplace:

200 Response
{
  "currency": "USD", "source": "phases",
  "phases": {
    "Emerald": {
      "skinport": [ { "date": "2026-07-15", "price": 57856, "quantity": 2 } ],
      "dmarket":  [ { "date": "2026-07-15", "price": 62999, "quantity": 9 } ]
    },
    "Phase 1": {
      "skinport": [ { "date": "2026-07-15", "price": 13876, "quantity": 4 } ]
    }
  }
}

Bulk price history

POST/api/v1/items/history1× Price historyAPI key

Daily price + quantity on each marketplace (including the Steam ask), for up to 100 items in one request - one series per market, per item. Pick the daily value with metric (close default, low or avg). The bulk companion to Price history source=markets; unmatched names are listed in missing. Counts as one request against your quota.

FieldInDescription
names requiredbodyArray of market hash names (max 100).
metricbodyWhich daily value per market: close (default), low or avg.
daysbodyHistory window in days (1-365, default 30) - or from / to ISO dates.
gamebodyGame slug to disambiguate (e.g. cs2).
currencyqueryOptional output currency (e.g. EUR).
Request
curl -X POST "https://api.example.com/api/v1/items/history" \
  -H "Authorization: Bearer sdk_…" \
  -H "Content-Type: application/json" \
  -d '{ "game": "cs2", "days": 30, "names": ["AK-47 | Redline (Field-Tested)"] }'
200 Response
{
  "currency": "USD",
  "requested": 1, "matched": 1, "missing": [],
  "data": [
    {
      "marketHashName": "AK-47 | Redline (Field-Tested)", "found": true,
      "markets": {
        "steam": [
          { "date": "2026-07-15", "price": 4225, "quantity": 1125 }
        ],
        "skinport": [
          { "date": "2026-07-14", "price": 2531, "quantity": 80 },
          { "date": "2026-07-15", "price": 2519, "quantity": 77 }
        ]
      }
    }
  ]
}

Collections

GET/api/v1/collections1× CollectionsAPI key

List item collections for a game, with counts. Pass with_items=true to embed the skins in each collection. Each collection carries its set icon (image) from the game files - mirrored onto our CDN, safe to hotlink.

ParamInDescription
gamequeryGame slug (defaults to cs2).
with_itemsquerytrue to embed each collection's skins.
Request
curl "https://api.example.com/api/v1/collections?game=cs2" \
  -H "Authorization: Bearer sdk_…"
200 Response
{
  "game": "cs2",
  "total": 95,
  "data": [
    { "collection": "The Phoenix Collection", "slug": "the-phoenix-collection",
      "image": "/images/60/60df70….img", "itemCount": 112 },
    { "collection": "Broken Fang Agents",     "slug": "broken-fang-agents",
      "image": "/images/8a/8a41bc….img", "itemCount": 20 }
  ]
}

Collection by name

GET/api/v1/collections/:name1× CollectionsAPI key

List the skins within a single collection (URL-encoded name), e.g. The%20Phoenix%20Collection. Paginated; each entry is the same full item object the Single item endpoint returns.

ParamInDescription
name requiredpathURL-encoded collection name.
gamequeryGame slug (defaults to cs2).
page · limitquery1-based page number · items per page (default 100).
currencyqueryOptional output currency (e.g. EUR).
Request
curl "https://api.example.com/api/v1/collections/The%20Phoenix%20Collection?game=cs2" \
  -H "Authorization: Bearer sdk_…"
200 Response (truncated)
{
  "collection": "The Phoenix Collection", "slug": "the-phoenix-collection", "image": "/images/60/60df70….img", "game": "cs2",
  "total": 112, "page": 1, "limit": 100, "currency": "USD",
  "data": [
    {
      "marketHashName": "AK-47 | Redline (Field-Tested)",
      "rarity": "Classified", "wear": "ft", "isStattrak": false,
      "prices": { "best": 2519, "bestSource": "skinport", "latest": 4225, "real": 3021 },
      "volume": { "sold24h": 76 }
    }
  ]
}

Crates & capsules

GET/api/v1/crates1× Bulk pricesAPI key

Every openable container in the game - weapon cases, sticker / autograph / patch capsules, souvenir packages and music kit boxes - with per-crate content counts. rareCount covers the case's rare special item pool (knives & gloves), which Steam's own contents list never names. Pass with_items=true to embed full drop tables; rare pool entries carry isRare: true. Deliberately price-free: drop tables are static structure - join All items & prices by marketHashName for live prices.

ParamInDescription
gamequeryGame slug (defaults to cs2).
typequeryFilter to one container type: case, sticker_capsule, autograph_capsule, patch_capsule, souvenir_package, music_kit_box, graffiti_box, pin_capsule, souvenir_highlight, other.
with_itemsquerytrue to embed each crate's contents (slim item shape + isRare).
imagesquery1 to include image URLs (crate + contents). Opt-in - icon URLs roughly double a full dump.
Request
curl "https://api.example.com/api/v1/crates?type=case&images=1" \
  -H "Authorization: Bearer sdk_…"
200 Response (truncated)
{
  "game": "cs2",
  "total": 42,
  "data": [
    { "crate": "Chroma 2 Case", "slug": "chroma-2-case", "type": "case",
      "image": "https://community.akamai.steamstatic.com/economy/image/…",
      "itemCount": 128, "rareCount": 178 }
  ]
}

Crate by name

GET/api/v1/crates/:name1× Bulk pricesAPI key

Everything one crate drops (URL-encoded name or slug), paginated - slim item identities plus isRare, listed contents first, then the rare pool, names A-Z. rare=only answers "which knives / gloves can this case open" - e.g. every Doppler, Marble Fade and Tiger Tooth variant behind Chroma 2's Exceedingly Rare Item slot. Price-free by design: join All items & prices by marketHashName.

ParamInDescription
name requiredpathURL-encoded crate name or slug (chroma-2-case).
gamequeryGame slug (defaults to cs2).
rarequeryinclude (default) · only (just the knife/glove pool) · exclude.
page · limitquery1-based page number · items per page (default 100, max 500).
Request
curl "https://api.example.com/api/v1/crates/chroma-2-case?rare=only" \
  -H "Authorization: Bearer sdk_…"
200 Response (truncated)
{
  "crate": "Chroma 2 Case", "slug": "chroma-2-case", "type": "case", "game": "cs2",
  "total": 178, "page": 1, "limit": 100,
  "data": [
    {
      "marketHashName": "★ Karambit | Doppler (Factory New)",
      "weaponType": "Knife", "rarity": "Covert", "wear": "fn",
      "image": "https://community.akamai.steamstatic.com/economy/image/…",
      "isRare": true
    }
  ]
}

Inventory

GET/api/v1/inventory/:steamid1× Inventory+1× Inventory?fresh=1+1× Marketplaces?markets=1API key

Return every item in a user's public CS2 or Rust inventory, enriched with our stored prices and a Steam-price inventory total. For CS2, each item includes float (wear), pattern (paint seed), paint index read directly from Steam - no inspect service needed - plus a derived Doppler/Gamma phase (Ruby, Sapphire, Phase 1-4, Emerald…), a fade percentage for Fade/Amber/Acid Fade skins, and a blue-gem tier (Tier 1-3) + rank & blue coverage for Case Hardened / Heat Treated skins. Applied stickers, charms and patches come back named, with each sticker's scrape percentage (wear, 0 = unscraped). Stickers carry no price - applying one is permanent and scraping destroys it, so it can never be sold off the gun. Charms and patches detach intact, so those are priced. The response also includes the owner's Steam profile (persona name, avatar, profile URL) - resolved as part of the same lookup, no extra request.

ParamInDescription
steamid requiredpathA 17-digit steamID64, a full profile URL (/profiles/… or /id/…), or a vanity name.
gamequerycs2 (default) or rust. Float/pattern/paint-index are CS2-only.
currencyqueryOptional output currency (e.g. EUR).
freshquerytrue/1 bypasses the ~24h cache and forces a live Steam fetch - bills one extra Inventory request.
marketsquerytrue/1 adds a markets array to every item - the latest price & stock on each third-party marketplace (CSFloat, Skinport, Buff163, YouPin, C5Game, DMarket, Waxpeer, Lis-Skins, SkinBaron, HaloSkins, WhiteMarket). Requires a plan with Marketplaces access (Scale+) and bills one Marketplaces request on top of the lookup.
formatqueryjson (default), csv - one row per item, spreadsheet-ready - or xml. gzip is automatic via Accept-Encoding.
Results are cached ~24h per inventory, so a repeat lookup is instant and counts as a normal request. Need current data? Add ?fresh=1 to force a live fetch from Steam - that call bills as one extra request. The markets breakdown is joined from our latest stored marketplace prices on every call, so it stays current even when the item list is served from the cache. Every market row carries an icon - an absolute URL to that marketplace's favicon, ready to render next to the price.
Sticker Slabs are priced as the sticker inside them. A slab is a display case for one sticker and carries no value of its own, so a held Sticker Slab | Crown (Foil) is valued - prices and marketplace breakdown alike - from Sticker | Crown (Foil). The item keeps its own name and icon in the response.
Doppler / Gamma phases. Steam sells every phase under one market hash name, so a blended price would show a Sapphire at the Phase-1 floor. For assets with a detected phase, the markets rows and prices.real / realMedian / realMarket are that phase's own cross-market prices (from the phase-aware markets: Buff163, DMarket, HaloSkins, Lis-Skins, SkinBaron, Skinport, Waxpeer, WhiteMarket); markets without per-phase data are omitted for those assets. prices.latest / median / buyorder remain the shared Steam listing.
Empty vs private: a reachable inventory with no items is a normal 200 with "status": "empty" and items: []. A private inventory (or private profile) returns 403 inventory_private. If Steam transiently rate-limits the live fetch you'll get 503 rate_limited - retry shortly.
Total value - two bases. summary.totalValue.steamPrice sums the inventory at Steam Community Market prices (each item's lowest ask). One quirk to know: Steam caps listings at ~$1,800, so anything worth more - a Dragon Lore, a top-tier knife - is counted at the cap and undervalued. Pass ?markets=1 for totalValue.realAvg too: the inventory summed at the mean of the third-party markets (Buff163, CSFloat, Skinport…), uncapped. Third-party markets usually price a bit below Steam (they carry no Steam fee), so realAvg typically runs a touch lower than steamPrice - except on those capped ultra-rares, where it's the truer number. Treat the two as a bracket: Steam-market vs third-party. Each item also carries prices.realMedian if you'd rather total the outlier-resistant median yourself.
Request
curl "https://api.example.com/api/v1/inventory/76561198305185709?game=cs2&currency=EUR&markets=1" \
  -H "Authorization: Bearer sdk_…"
200 Response (truncated)
{
  // "empty" = reachable inventory with zero items (still a 200)
  "status": "ok",
  "steamid": "76561198305185709",
  "profile": { "name": "Dankan", "avatar": "https://avatars.steamstatic.com/…_full.jpg", "avatarMedium": "https://avatars.steamstatic.com/…_medium.jpg", "url": "https://steamcommunity.com/profiles/76561198305185709" },
  "game": "cs2",
  "currency": "EUR",
  "summary": { "items": 708, "totalInventoryCount": 723,
    // steamPrice = Σ Steam ask (capped ~$1,800/item); realAvg (only with ?markets=1) = Σ mean across markets - usually a bit lower
    "totalValue": { "steamPrice": 3984210, "realAvg": 3418670 } },
  "items": [
    {
      "assetid": "52242499929",
      "marketHashName": "★ Bayonet | Doppler (Factory New)",
      "exterior": "Factory New", "rarity": "Covert",
      "float": 0.0373989, "paintSeed": 358, "paintIndex": 419,
      "phase": "Phase 2", "fade": null,
      "blueGem": { "tier": "Tier 1", "rank": 1, "totalRanked": 1001, "playsideBlue": 97.64, "backsideBlue": 19.22 },
      "nameTag": null, "inspectLink": "steam://rungame/730/…",
      // wear = scrape %, 0 = unscraped. No price: an applied sticker can't be sold off the gun.
      "stickers": [
        { "name": "Sticker | G2 Esports | Katowice 2019", "wear": 0, "classid": "3186046174", "image": "https://community.cloudflare…" },
        { "name": "Sticker | donk (Champion) | Shanghai 2024", "wear": 0.68, "classid": "6449443157", "image": "https://community.cloudflare…" }
      ],
      // charms/patches detach intact, so they keep a price and have no wear.
      "charms": [
        { "name": "Charm | Pinch O' Salt", "price": 12, "classid": "6216354694", "image": "https://community.cloudflare…" }
      ],
      "patches": [],
      // only with ?markets=1 - latest price & stock per marketplace (icon = the marketplace's favicon).
      // This asset is a Doppler, so these are PHASE 2 prices from the phase-aware markets -
      // markets without per-phase data are omitted rather than shown at the blended-name price.
      "markets": [
        { "market": "buff163", "icon": "https://steamdataapi.com/img/markets/buff163-c.png", "price": 36890, "quantity": 12, "capturedAt": "2026-07-21T09:10:00.000Z" },
        { "market": "dmarket", "icon": "https://steamdataapi.com/img/markets/dmarket-c.png", "price": 37350, "quantity": 6, "capturedAt": "2026-07-21T09:12:00.000Z" }
      ],
      "prices": {
        "latest": 38657, "median": 38104, "buyorder": 36500,
        // phase-aware for Doppler/Gamma: this Phase 2's own lowest / median / cheapest market
        "real": 36890, "realMedian": 37120, "realMarket": "buff163",
        "value": 37980
      }
    }
  ]
}