OmniStream
← Marketplace
Gaming verified

SkinAPI

Steam & CS2 data API.

https://skinapi.skinvaults.online17 endpointsapiKey auth4.8 (214)99.6% uptime
Install
shell
npm install @omnistream/skinapi
example.ts
import { SkinAPI } from "@omnistream/skinapi";

// One Omni key reaches every API on the marketplace.
const api = new SkinAPI(process.env.OMNI_KEY);

const data = await api.markets({ /* params */ });
Auto-generated SDK
skinapi.ts
/**
 * SkinAPI - generated by OmniStream from SkinAPI's OpenAPI spec.
 * One typed method per endpoint. A single Omni key reaches the API.
 */
const DEFAULT_BASE = "https://grid.omnistream.dev/v1/proxy/skinapi";

export class SkinAPIError extends Error {
  status: number;
  code?: string;
  constructor(status: number, code: string | undefined, message?: string) {
    super(message || `SkinAPI error ${status}`);
    this.name = "SkinAPIError";
    this.status = status;
    this.code = code;
  }
}

export interface SkinAPIOptions {
  baseUrl?: string;
  fetch?: typeof fetch;
  timeoutMs?: number;
}

export class SkinAPI {
  /** @param token Your OmniStream key (one key for every API). */
  constructor(private token: string, private opts: SkinAPIOptions = {}) {
    if (!token) throw new Error("SkinAPI: token is required");
  }
  rateLimit: { remainingMinute?: number; remainingDay?: number } | null = null;

  private async _request(method: string, path: string, { params, body }: { params?: Record<string, unknown>; body?: unknown } = {}): Promise<any> {
    const f = this.opts.fetch ?? globalThis.fetch;
    const url = new URL((this.opts.baseUrl ?? DEFAULT_BASE).replace(/\/+$/, "") + path);
    if (params) for (const [k, v] of Object.entries(params)) if (v != null) url.searchParams.set(k, String(v));
    const headers: Record<string, string> = { "x-omni-key": this.token };
    if (body !== undefined) headers["content-type"] = "application/json";
    const res = await f(url, { method, headers, body: body !== undefined ? JSON.stringify(body) : undefined });
    this.rateLimit = {
      remainingMinute: Number(res.headers.get("x-ratelimit-remaining-minute")) || undefined,
      remainingDay: Number(res.headers.get("x-ratelimit-remaining-day")) || undefined,
    };
    const data = await res.json().catch(() => ({}));
    if (!res.ok) throw new SkinAPIError(res.status, data?.error?.code, data?.error?.message);
    return data.data ?? data;
  }

  /** Unified price for an item across every tracked marketplace. */
  markets(params: { "name": string; "game"?: string; "currency"?: string }): Promise<any> {
    return this._request("GET", "/api/v1/markets", { params });
  }

  /** Price up to 20 items across all markets in one call. */
  marketsBatch(body: unknown): Promise<any> {
    return this._request("POST", "/api/v1/markets/batch", { body });
  }

  /** Current price for an item (cached Steam Market, live fallback). */
  items(params: { "name": string; "game"?: string; "currency"?: string }): Promise<any> {
    return this._request("GET", "/api/v1/items", { params });
  }

  /** Daily price history (cross-source average + volume). Returns up to 365 days. */
  history(params: { "name": string; "game"?: string; "days"?: string; "currency"?: string }): Promise<any> {
    return this._request("GET", "/api/v1/history", { params });
  }

  /** Deal finder: items priced below Steam across markets. */
  deals(params: { "game"?: string; "min_discount"?: string; "currency"?: string }): Promise<any> {
    return this._request("GET", "/api/v1/deals", { params });
  }

  /** Exact float, paint seed, pattern (Doppler phase, blue-gem tier, Fire&Ice), stickers with images and sticker value (USD), and item name+image. */
  float(params: { "url": string }): Promise<any> {
    return this._request("GET", "/api/v1/float", { params });
  }

  /** Lowest (or highest) float leaderboard for a skin. */
  floatLeaderboard(params: { "name": string; "order"?: string; "limit"?: string }): Promise<any> {
    return this._request("GET", "/api/v1/float/leaderboard", { params });
  }

  /** Public inventory priced per item with total value, plus a summary (rarity breakdown, tradable/marketable counts, top items). Supports any game. */
  inventory(params: { "steam_id": string; "game"?: string; "prices"?: string; "currency"?: string }): Promise<any> {
    return this._request("GET", "/api/v1/inventory", { params });
  }

  /** Up to 10 inventories in a single request. */
  inventoryBatch(body: unknown): Promise<any> {
    return this._request("POST", "/api/v1/inventory/batch", { body });
  }

  /** Daily value-over-time history for a tracked inventory. */
  inventoryHistory(params: { "steam_id": string; "game"?: string; "days"?: string; "currency"?: string }): Promise<any> {
    return this._request("GET", "/api/v1/inventory/history", { params });
  }

  /** Steam profile with level, CS2 playtime (hours), VAC/trade/community ban status, avatar and country. */
  profile(params: { "id": string }): Promise<any> {
    return this._request("GET", "/api/v1/profile", { params });
  }

  /** Friend list with friendship timestamps. */
  friendlist(params: { "steam_id": string }): Promise<any> {
    return this._request("GET", "/api/v1/friendlist", { params });
  }

  /** Full paginated item catalog (up to 500/page). CS2 returns all ~15K wear-specific items from the asset DB with image, type and rarity. Other games return names seen in the prices collection. Add ?prices=true to include the lowest known price per item. */
  catalog(params: { "game"?: string; "limit"?: string; "offset"?: string; "q"?: string; "type"?: string; "rarity"?: string; "prices"?: string; "sort"?: string; "currency"?: string }): Promise<any> {
    return this._request("GET", "/api/v1/catalog", { params });
  }

  /** Search the CS2 item database by name (autocomplete). */
  itemsSearch(params: { "q"?: string; "limit"?: string }): Promise<any> {
    return this._request("GET", "/api/v1/items/search", { params });
  }

  /** Full metadata for an item (weapon, rarity, collection, crates, float range). */
  itemsMeta(params: { "name": string }): Promise<any> {
    return this._request("GET", "/api/v1/items/meta", { params });
  }

  /** Trade-up calculator: 10 items of the same rarity + collection -> possible outcomes, probabilities, EV. */
  tradeup(body: unknown): Promise<any> {
    return this._request("POST", "/api/v1/tradeup", { body });
  }

  /** Public component health: DB connectivity, price ingest freshness, Buff source status, market source reachability. No auth required. */
  status(): Promise<any> {
    return this._request("GET", "/api/v1/status", {});
  }
}

export default SkinAPI;
Endpoints
GET/api/v1/markets

Unified price for an item across every tracked marketplace.

name*gamecurrency
POST/api/v1/markets/batch

Price up to 20 items across all markets in one call.

GET/api/v1/items

Current price for an item (cached Steam Market, live fallback).

name*gamecurrency
GET/api/v1/history

Daily price history (cross-source average + volume). Returns up to 365 days.

name*gamedayscurrency
GET/api/v1/deals

Deal finder: items priced below Steam across markets.

gamemin_discountcurrency
GET/api/v1/float

Exact float, paint seed, pattern (Doppler phase, blue-gem tier, Fire&Ice), stickers with images and sticker value (USD), and item name+image.

url*
GET/api/v1/float/leaderboard

Lowest (or highest) float leaderboard for a skin.

name*orderlimit
GET/api/v1/inventory

Public inventory priced per item with total value, plus a summary (rarity breakdown, tradable/marketable counts, top items). Supports any game.

steam_id*gamepricescurrency
POST/api/v1/inventory/batch

Up to 10 inventories in a single request.

GET/api/v1/inventory/history

Daily value-over-time history for a tracked inventory.

steam_id*gamedayscurrency
GET/api/v1/profile

Steam profile with level, CS2 playtime (hours), VAC/trade/community ban status, avatar and country.

id*
GET/api/v1/friendlist

Friend list with friendship timestamps.

steam_id*
GET/api/v1/catalog

Full paginated item catalog (up to 500/page). CS2 returns all ~15K wear-specific items from the asset DB with image, type and rarity. Other games return names seen in the prices collection. Add ?prices=true to include the lowest known price per item.

gamelimitoffsetqtyperaritypricessortcurrency
GET/api/v1/items/search

Search the CS2 item database by name (autocomplete).

qlimit
GET/api/v1/items/meta

Full metadata for an item (weapon, rarity, collection, crates, float range).

name*
POST/api/v1/tradeup

Trade-up calculator: 10 items of the same rarity + collection -> possible outcomes, probabilities, EV.

GET/api/v1/status

Public component health: DB connectivity, price ingest freshness, Buff source status, market source reachability. No auth required.

Console
Try itone Omni key, every API
GET/api/v1/status