npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

steamdataapi

v1.0.0

Published

Steam Market API and Steam Inventory API client for Node.js — live CS2 and Rust skin prices from Steam and 10 marketplaces, daily price history back to 2013, and whole-inventory valuation with floats. Typed, zero dependencies.

Readme

steamdataapi

Steam Market API and Steam Inventory API client for Node.js and TypeScript.

Live CS2 and Rust skin prices from the Steam Community Market and 10 third-party marketplaces (Skinport, CSFloat, Buff163, DMarket, Waxpeer, Lis-Skins, SkinBaron, WhiteMarket, YouPin, C5Game), daily price history back to 2013, Doppler phase prices, case drop tables, and whole-inventory valuation with floats and patterns — through one typed client with zero dependencies.

Backed by steamdataapi.com. Free API key, no card.

npm install steamdataapi

Works on Node 18+, Bun, Deno and browsers (see the note on keys below).

Quick start

import { SteamDataApi } from 'steamdataapi';

const api = new SteamDataApi('sdk_your_api_key'); // https://steamdataapi.com/app

// One item — every price field, plus where it is cheapest right now
const item = await api.items.get('AK-47 | Redline (Field-Tested)', { game: 'cs2' });
console.log(item.prices.best, item.prices.bestSource); // 1690 'csfloat'  (integer cents)

// A whole public inventory, valued — with floats, pattern seeds and Doppler phases
const inv = await api.inventory('76561198305185709', { game: 'cs2', currency: 'EUR' });
console.log(inv.summary.totalValue.steamPrice, inv.items.length);

// 30 days of daily prices on every marketplace
const history = await api.items.history('★ Karambit | Doppler (Factory New)', { source: 'markets', days: 30 });
console.log(Object.keys(history.markets)); // ['steam', 'skinport', 'csfloat', …]

All prices are integers in minor units (cents) of the response's currency, never floats. A price is null when a market has no current listing.

What's covered

| Method | Endpoint | Notes | | --- | --- | --- | | api.items.get(name, opts) | GET /items/:name | Metadata, all price fields, Doppler variants; markets: true embeds per-marketplace rows | | api.items.all(opts) | GET /items/all | The price sheet — every item for a game in one call (~4 MB) | | api.items.prices(names, opts) | POST /items/prices | Up to 500 items in one request | | api.items.markets(name, opts) | GET /items/:name/markets | Every marketplace's current price, the best one and the spread | | api.items.marketsBulk(names, opts) | POST /items/markets | Same, up to 100 items | | api.items.history(name, opts) | GET /items/:name/history | source: 'steam' \| 'markets' \| 'phases'; days or from/to; metric: 'close' \| 'low' \| 'avg' | | api.items.historyBulk(names, opts) | POST /items/history | Per-market daily series, up to 100 items | | api.inventory(steamid, opts) | GET /inventory/:steamid | SteamID64, profile URL or vanity name; fresh: true bypasses the cache; markets: true adds per-market rows | | api.collections.list(opts) / .get(name) | GET /collections[/:name] | Collections with set icons; items inside one collection | | api.crates.list(opts) / .get(name) | GET /crates[/:name] | Cases, capsules and packages with full drop tables; rare: 'only' for the knife/glove pool | | api.currencies() · api.plans() | GET /currencies · /plans | Accepted currency codes; plan limits |

Full reference with every parameter and a sample response for each: steamdataapi.com/docs.

Examples

Cheapest marketplace for a list of items — one request, not a hundred:

const { data, missing } = await api.items.marketsBulk(
  ['AWP | Asiimov (Field-Tested)', 'M4A4 | Howl (Minimal Wear)'],
  { game: 'cs2' },
);
for (const row of data) {
  if (row.found) console.log(row.marketHashName, row.best?.market, row.best?.price, 'spread', row.spread);
}
console.log('not in catalog:', missing);

Mirror every price locally — poll the sheet, join by marketHashName:

const sheet = await api.items.all({ game: 'cs2' });
const byName = new Map(sheet.data.map((r) => [r.marketHashName, r.prices]));
console.log(sheet.count, 'items as of', sheet.cachedAt);

Value an inventory in your currency, with the uncapped third-party total:

const inv = await api.inventory('https://steamcommunity.com/id/someone', { currency: 'EUR', markets: true });
console.log('Steam:', inv.summary.totalValue.steamPrice / 100, 'EUR');
console.log('Markets:', (inv.summary.totalValue.realAvg ?? 0) / 100, 'EUR');
for (const it of inv.items) {
  console.log(it.marketHashName, it.float, it.phase ?? '', it.prices.value);
}

Rust works the same way — pass game: 'rust':

const rust = await api.items.all({ game: 'rust' }); // every Rust item, priced
const door = await api.items.get('Metal Door', { game: 'rust' });

Errors and retries

Every non-2xx response throws a SteamDataApiError carrying the API's error code and message, plus a few helpers:

import { SteamDataApiError } from 'steamdataapi';

try {
  await api.items.history('x', { source: 'markets' });
} catch (err) {
  if (err instanceof SteamDataApiError) {
    err.status;           // 429
    err.code;             // 'quota_exceeded'
    err.quotaGroup;       // 'history' — which endpoint group ran out
    err.isQuotaExceeded;  // true — do not retry until it resets
    err.isRateLimited;    // per-minute limiter — the client already retried this
    err.isPlanForbidden;  // endpoint not in your plan
    err.reason;           // for 401: 'missing' | 'scheme' | 'api_key' | 'session'
  }
}

The client retries automatically — honouring retry-after — on the per-minute rate limit, on Steam's transient 503 rate_limited during inventory reads, and on 502/504. It never retries an exhausted daily or monthly quota. Tune with maxRetries (default 2) and timeoutMs (default 30 000).

Options

const api = new SteamDataApi('sdk_…', {
  currency: 'EUR',          // default for every price-bearing call; per-call `currency` wins
  timeoutMs: 30_000,
  maxRetries: 2,
  baseUrl: 'https://steamdataapi.com/api/v1', // self-hosted instances
  fetch: myFetch,           // bring your own (defaults to the global fetch)
  headers: { 'X-Trace': '…' },
});

TypeScript

Every response is typed (Item, PriceSheet, InventoryResponse, MarketsHistoryResponse, …) from the published reference. items.history narrows its return type on source. Fields this version does not know about are still passed through.

Keys in browsers

The client runs in browsers, but an API key in a browser bundle is public — anyone can read it and spend your quota. Call the API from your own backend and send your frontend the results.

Links

  • Docs: https://steamdataapi.com/docs
  • Get a key: https://steamdataapi.com/app
  • Pricing and per-endpoint limits: https://steamdataapi.com/pricing
  • CS2 skin API: https://steamdataapi.com/cs2-api · Rust skin API: https://steamdataapi.com/rust-api
  • Steam market API: https://steamdataapi.com/steam-market-api · Steam inventory API: https://steamdataapi.com/steam-inventory-api
  • Python client: https://pypi.org/project/steamdataapi/

License

MIT © Steam Data API. Not affiliated with Valve or Steam.