SkinAPI
Steam & CS2 data API.
npm install @omnistream/skinapiimport { 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 */ });/**
* 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;
Unified price for an item across every tracked marketplace.
Price up to 20 items across all markets in one call.
Current price for an item (cached Steam Market, live fallback).
Daily price history (cross-source average + volume). Returns up to 365 days.
Deal finder: items priced below Steam across markets.
Exact float, paint seed, pattern (Doppler phase, blue-gem tier, Fire&Ice), stickers with images and sticker value (USD), and item name+image.
Lowest (or highest) float leaderboard for a skin.
Public inventory priced per item with total value, plus a summary (rarity breakdown, tradable/marketable counts, top items). Supports any game.
Up to 10 inventories in a single request.
Daily value-over-time history for a tracked inventory.
Steam profile with level, CS2 playtime (hours), VAC/trade/community ban status, avatar and country.
Friend list with friendship timestamps.
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.
Search the CS2 item database by name (autocomplete).
Full metadata for an item (weapon, rarity, collection, crates, float range).
Trade-up calculator: 10 items of the same rarity + collection -> possible outcomes, probabilities, EV.
Public component health: DB connectivity, price ingest freshness, Buff source status, market source reachability. No auth required.