npm install omnistream-sdkimport { OmniClient } from "omnistream-sdk";
const omni = new OmniClient({ token: process.env.OMNI_KEY! });
// One key reaches every API on the marketplace.
const data = await omni.call("skinapi/markets");One install, one key - the same client calls every API on the marketplace.
Unified price for an item across all 11 tracked marketplaces. All money values are integer MINOR units (cents): 2813 means 28.13. Every response carries a `unit` field so you never have to guess.
Price up to 20 items across all markets in one call.
Current price for an item (cached Steam Market, live fallback). NOTE: `price` is a MAJOR-unit decimal (42.16) - the only endpoint that is; every other price endpoint returns integer cents. Each response carries a `unit` field.
Daily price history (cross-source average + volume). Returns up to 365 days.
Deal finder: items priced below Steam across markets.
/**
* 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.skinvaults.online/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 all 11 tracked marketplaces. All money values are integer MINOR units (cents): 2813 means 28.13. Every response carries a `unit` field so you never have to guess. */
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). NOTE: `price` is a MAJOR-unit decimal (42.16) - the only endpoint that is; every other price endpoint returns integer cents. Each response carries a `unit` field. */
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 });
}
/** Bulk market feed: floor, cross-market spread, top buy order, supply and 7d change for the whole catalogue in one call. Page size scales with your plan (free 100 > enterprise 10,000). */
feed(params: { "game"?: string; "limit"?: string; "offset"?: string; "min_sources"?: string; "sort"?: string; "currency"?: string }): Promise<any> {
return this._request("GET", "/api/v1/feed", { params });
}
/** Biggest gainers and losers over a window, from daily price history. Penny items and newly-tracked items are filtered out so the list is real movement, not noise. */
movers(params: { "game"?: string; "days"?: string; "direction"?: string; "min_price"?: string; "limit"?: string; "currency"?: string }): Promise<any> {
return this._request("GET", "/api/v1/movers", { params });
}
/** Aggregate market index (rebased to 1000 at first snapshot) with history and a per-marketplace breakdown. itemCount is returned per point so coverage changes can be told apart from real moves. */
index(params: { "game"?: string; "days"?: string; "currency"?: string }): Promise<any> {
return this._request("GET", "/api/v1/index", { params });
}
/** Fee-aware arbitrage: buy the cheapest listing, sell where the net return after commission is highest. Returns buyFrom/sellTo, netProfit, roi and a confidence flag. Unlike /deals, the numbers are after fees. */
arbitrage(params: { "game"?: string; "min_profit"?: string; "min_roi"?: string; "limit"?: string; "currency"?: string }): Promise<any> {
return this._request("GET", "/api/v1/arbitrage", { 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 });
}
/** Price a specific item instance: the float picks the wear bucket, the paint seed surfaces pattern premiums (Doppler phase, blue gem, Fire & Ice). Returns the full wear price curve, and real per-phase Doppler prices where available. */
floatPrice(params: { "name": string; "float"?: string; "paint_seed"?: string; "paint_index"?: string; "game"?: string; "currency"?: string }): Promise<any> {
return this._request("GET", "/api/v1/float/price", { params });
}
/** Live Steam order-book depth for a CS2 item: bid/ask ladder, spread, total buy/sell interest, plus the Buff buy-order as a cross-venue instant-sell reference. No other public CS2 API exposes this. */
orderbook(params: { "name": string; "depth"?: string; "currency"?: string }): Promise<any> {
return this._request("GET", "/api/v1/orderbook", { 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 });
}
/** Autocomplete over the CS2 skin schema. Returns BASE names (no wear suffix) - good for a picker; use /search if you need a name you can price directly. */
itemsSearch(params: { "q"?: string; "limit"?: string }): Promise<any> {
return this._request("GET", "/api/v1/items/search", { params });
}
/** Search the tracked item database (any game) and get exact market_hash_names WITH the wear suffix, plus image and rarity. These are the names /markets, /items and /history expect - start here when a price lookup returns missing_wear. */
search(params: { "q": string; "game"?: string; "limit"?: string }): Promise<any> {
return this._request("GET", "/api/v1/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 });
}
/** CS2 cases, capsules and collections: every set with its full item pool, the rare knife/glove pool, release date and live container price. */
collections(params: { "name"?: string; "q"?: string; "kind"?: string; "type"?: string; "contents"?: string; "prices"?: string; "limit"?: string; "offset"?: string; "currency"?: string }): Promise<any> {
return this._request("GET", "/api/v1/collections", { params });
}
/** Live USD-based FX rates - the same table every price endpoint uses for ?currency=. Pass from/to/amount to convert a single value. */
currency(params: { "from"?: string; "to"?: string; "amount"?: string }): Promise<any> {
return this._request("GET", "/api/v1/currency", { params });
}
/** Resolve a SteamID64, vanity name or pasted profile URL to every ID format (SteamID64, STEAM_1:Y:Z, [U:1:id], account id). */
resolve(params: { "id": string }): Promise<any> {
return this._request("GET", "/api/v1/resolve", { 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 });
}
/** List every price alert on your account. Each fires when an item's lowest price crosses your threshold, via webhook, Discord and/or email. */
alertsList(): Promise<any> {
return this._request("GET", "/api/v1/alerts", {});
}
/** Create a price alert. threshold is in your currency (e.g. 40 with currency=EUR) and fires when the item's lowest price goes below (or above) it. Provide at least one channel. */
alertsCreate(body: unknown): Promise<any> {
return this._request("POST", "/api/v1/alerts", { body });
}
/** Fetch a single alert by id. */
alertsGet(params: { "id": string }): Promise<any> {
return this._request("GET", "/api/v1/alerts/{id}", { params });
}
/** Update an alert. Only the fields you send change; pass a channel as "" to clear it, active=false to pause. */
alertsUpdate(body: unknown, params: { "id": string }): Promise<any> {
return this._request("PATCH", "/api/v1/alerts/{id}", { body, params });
}
/** Delete an alert. */
alertsDelete(params: { "id": string }): Promise<any> {
return this._request("DELETE", "/api/v1/alerts/{id}", { params });
}
/** Find profitable trade-up contracts ranked by return on cost after fees. Scans single-collection contracts (10x the same skin) across every collection, rarity and wear. Verify a candidate with POST /v1/tradeup before crafting - input floats here are assumed. */
tradeupSearch(params: { "max_cost"?: string; "min_roi"?: string; "rarity"?: string; "collection"?: string; "liquid_only"?: string; "sell_on"?: string; "limit"?: string; "currency"?: string }): Promise<any> {
return this._request("GET", "/api/v1/tradeup/search", { params });
}
/** Case/capsule opening expected value: per-rarity odds and average values, the knife/glove pool, EV after sell fees, break-even case price and the chance of profiting. Unboxing is gambling - for almost every case the EV is below the key price. */
unbox(params: { "name": string; "key_price"?: string; "sell_on"?: string; "currency"?: string }): Promise<any> {
return this._request("GET", "/api/v1/unbox", { params });
}
/** 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", {});
}
/** Minimal liveness probe: { status, db, time }. No API key required - intended for uptime monitors and load-balancer checks. Use /status for per-component detail. */
health(): Promise<any> {
return this._request("GET", "/api/v1/health", {});
}
}
export default SkinAPI;
No reviews yet. Be the first to rate this API.
No. SkinAPI is included with your Omni key, so a single OmniStream key is enough to start calling it. There is no separate signup with the provider and no second key to manage.
Steam & CS2 data API. It exposes 35 endpoints over GET, POST, PATCH, DELETE, including GET /api/v1/markets, POST /api/v1/markets/batch, GET /api/v1/items.
Install the OmniStream SDK for your language and call SkinAPI through it. The client is generated from this API's OpenAPI spec, so parameters and responses are fully typed, and the same client also calls every other API in the marketplace.
You can start on the free plan. OmniStream charges for the unified SDK, key storage and proxy rather than for SkinAPI itself.
Fortnite-API: Free Fortnite REST API for cosmetics, item shop, player stats, news, playlists, map, banners, AES keys, and creator codes.
Bulk market feed: floor, cross-market spread, top buy order, supply and 7d change for the whole catalogue in one call. Page size scales with your plan (free 100 > enterprise 10,000).
Biggest gainers and losers over a window, from daily price history. Penny items and newly-tracked items are filtered out so the list is real movement, not noise.
Aggregate market index (rebased to 1000 at first snapshot) with history and a per-marketplace breakdown. itemCount is returned per point so coverage changes can be told apart from real moves.
Fee-aware arbitrage: buy the cheapest listing, sell where the net return after commission is highest. Returns buyFrom/sellTo, netProfit, roi and a confidence flag. Unlike /deals, the numbers are after fees.
Exact float, paint seed, pattern (Doppler phase, blue-gem tier, Fire&Ice), stickers with images and sticker value (USD), and item name+image.
Price a specific item instance: the float picks the wear bucket, the paint seed surfaces pattern premiums (Doppler phase, blue gem, Fire & Ice). Returns the full wear price curve, and real per-phase Doppler prices where available.
Live Steam order-book depth for a CS2 item: bid/ask ladder, spread, total buy/sell interest, plus the Buff buy-order as a cross-venue instant-sell reference. No other public CS2 API exposes this.
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.
Autocomplete over the CS2 skin schema. Returns BASE names (no wear suffix) - good for a picker; use /search if you need a name you can price directly.
Search the tracked item database (any game) and get exact market_hash_names WITH the wear suffix, plus image and rarity. These are the names /markets, /items and /history expect - start here when a price lookup returns missing_wear.
Full metadata for an item (weapon, rarity, collection, crates, float range).
CS2 cases, capsules and collections: every set with its full item pool, the rare knife/glove pool, release date and live container price.
Live USD-based FX rates - the same table every price endpoint uses for ?currency=. Pass from/to/amount to convert a single value.
Resolve a SteamID64, vanity name or pasted profile URL to every ID format (SteamID64, STEAM_1:Y:Z, [U:1:id], account id).
Trade-up calculator: 10 items of the same rarity + collection -> possible outcomes, probabilities, EV.
List every price alert on your account. Each fires when an item's lowest price crosses your threshold, via webhook, Discord and/or email.
Create a price alert. threshold is in your currency (e.g. 40 with currency=EUR) and fires when the item's lowest price goes below (or above) it. Provide at least one channel.
Fetch a single alert by id.
Update an alert. Only the fields you send change; pass a channel as "" to clear it, active=false to pause.
Delete an alert.
Find profitable trade-up contracts ranked by return on cost after fees. Scans single-collection contracts (10x the same skin) across every collection, rarity and wear. Verify a candidate with POST /v1/tradeup before crafting - input floats here are assumed.
Case/capsule opening expected value: per-rarity odds and average values, the knife/glove pool, EV after sell fees, break-even case price and the chance of profiting. Unboxing is gambling - for almost every case the EV is below the key price.
Public component health: DB connectivity, price ingest freshness, Buff source status, market source reachability. No auth required.
Minimal liveness probe: { status, db, time }. No API key required - intended for uptime monitors and load-balancer checks. Use /status for per-component detail.