# How to get Rust skin prices with an API

> Get Rust skin prices from the same API as CS2: game-scoped pricing, NBBO, history, and item search with one game parameter. Runnable code included.

*Prices & quotes · Beginner · Updated 2026-09-25*

Rust skins trade on their own set of marketplaces, with their own listing formats and their own quirks, and there is far less tooling for them than for CS2. If you already price CS2 items with SkinPricer, you do not need a second integration: the same API serves Rust through game-scoped `/v2` routes that take one extra parameter. If you are starting with Rust, the same routes are the fastest way to get normalized, cross-market prices without collecting them yourself.

This guide covers how the game-scoped routes work, how to find a Rust item, how to read its best bid and ask and its price history, and what is genuinely different about Rust data compared with CS2.

## How the game-scoped routes work

Every `/v1` route is CS2 and stays exactly as documented. The core reads also exist as `/v2` routes that require a `game` query parameter, `game=rust` or `game=cs2`; any other value is a `400`. The response shapes are identical to their v1 counterparts, authentication is the same `Authorization: ApiKey <key>` header, and Rust is included in every plan with no add-on. CS2 and Rust calls draw from the same per-minute and monthly budget across all your keys. The [Games: CS2 & Rust](/api-docs/games) page is the full reference.

| GET route | Returns | Plan |
| --- | --- | --- |
| `/v2/items` | Catalog search with live pricing, paginated | Developer and up |
| `/v2/pricing/:marketHashName` | Per-market asks, buy orders, aggregate, best bid and ask | Developer and up |
| `/v2/nbbo` | Cross-market best bid and offer | Developer and up |
| `/v2/nbbo/depth` | Aggregated order-book depth | Developer and up |
| `/v2/pricing/:marketHashName/listings` | Individual listings | Developer and up |
| `/v2/pricing/:marketHashName/history` | Time-bucketed price history | Pro and up |
| `/v2/pricing/:marketHashName/history/markets` | History split per market | Pro and up |

Liquidity (`/v2/liquidity/:marketHashName`, `/v2/liquidity/summary/:marketHashName`, and `POST /v2/liquidity/batch`) and the item schema (`/v2/schema`, `/v2/schema/changes`, and `/v2/schema/items/:idOrName`) accept the same `game` parameter and keep their v1 plan requirements. Marketplace health for Rust is keyless at `https://api.skinpricer.com/v2/markets/health?game=rust`.

## Step 1: find the item

A Rust item is identified by its plain market hash name, which is the display name you see on the Steam market, for example `Tempered AK47` or `Big Grin`. There are no wear suffixes to append. When you only know part of a name, search the Rust catalog: `/v2/items` takes `search`, `markets`, `page`, and `perPage` (up to 100 per page). Search text is limited to 512 characters, and there is no `/v2/items/all`, so page through the search instead.

**curl**

```bash
export SKINPRICER_API_KEY="sp_live_•••"   # from your account's API keys page

curl -s "https://pricing.skinpricer.com/v2/items?game=rust&search=tempered&perPage=20" \
  -H "Authorization: ApiKey $SKINPRICER_API_KEY"
```

**Python**

```python
import os

import requests

res = requests.get(
    "https://pricing.skinpricer.com/v2/items",
    params={"game": "rust", "search": "tempered", "perPage": 20},
    headers={"Authorization": f"ApiKey {os.environ['SKINPRICER_API_KEY']}"},
    timeout=10,
)
res.raise_for_status()
for item in res.json()["data"]:
    ask = item.get("bestAsk")
    print(item["name"], ask and f"{ask['price'] / 100:.2f} USD on {ask['market']}")
```

## Step 2: read the best bid and ask

Call `/v2/nbbo` with `game=rust` and the item name. The response has the same shape as the [CS2 NBBO](/api-docs/nbbo): `bestAsk` and `bestBid` each name their venue, `spreadBps` measures the gap, and `confidence`, `freshMarketCount`, and the stale flags tell you how much to trust it. As with CS2, the default best bid only counts venues that pay sellers in cash. The TypeScript SDK wraps the v1 (CS2) routes today; game-scoped SDK methods arrive in a future SDK release, so call `/v2` over plain HTTP for now. The SDK's exported types still describe these responses exactly.

**curl**

```bash
curl -s "https://pricing.skinpricer.com/v2/nbbo?game=rust&market_hash_name=Tempered%20AK47" \
  -H "Authorization: ApiKey $SKINPRICER_API_KEY"
```

**Node (fetch)**

```ts
// Types only: npm i -D @skinpricer/sdk
import type { NbboResponse } from "@skinpricer/sdk";

const BASE = "https://pricing.skinpricer.com";
const headers = { Authorization: "ApiKey " + process.env.SKINPRICER_API_KEY };

async function rustGet<T>(path: string, params: Record<string, string>): Promise<T> {
  const url = new URL(path, BASE);
  url.searchParams.set("game", "rust");
  for (const [key, value] of Object.entries(params)) url.searchParams.set(key, value);

  const res = await fetch(url, { headers });
  if (res.status === 503) throw new Error("Rust reads are temporarily disabled; retry later");
  if (!res.ok) throw new Error("HTTP " + res.status + " on " + url.pathname);
  return (await res.json()) as T;
}

const nbbo = await rustGet<NbboResponse>("/v2/nbbo", { market_hash_name: "Tempered AK47" });

if (nbbo.bestAsk) console.log("Lowest ask:", nbbo.bestAsk.price / 100, "USD on", nbbo.bestAsk.market);
if (nbbo.bestBid) console.log("Best cash bid:", nbbo.bestBid.price / 100, "USD on", nbbo.bestBid.market);
console.log("Fresh venues:", nbbo.freshMarketCount, "| confidence:", nbbo.confidence);
```

**Response 200** (`GET /v1/nbbo`)

```json
{
  "marketHashName": "Glock-18 | Water Elemental (Factory New)",
  "canonicalItemId": "cmlofca920lka01yozajhixt3",
  "bestAsk": {
    "market": "csfloat",
    "price": 4373,
    "updatedAt": "2026-09-25T11:20:00.981Z",
    "isStale": false
  },
  "bestBid": {
    "market": "marketcsgo",
    "price": 4486,
    "updatedAt": "2026-09-25T11:20:03.070Z",
    "isStale": false
  },
  "spreadBps": -252,
  "marketCount": 16,
  "freshMarketCount": 15,
  "locked": false,
  "crossed": false,
  "confidence": 0.88,
  "executionAdjusted": {
    "bestAsk": {
      "market": "csfloat",
      "price": 4373,
      "rawPrice": 4373,
      "appliedFeeBps": 0,
      "executability": 0.51,
      "updatedAt": "2026-09-25T11:20:00.981Z",
      "isStale": false,
      "reasons": [
        "unknown_executable_depth"
      ]
    },
    "bestBid": {
      "market": "buff163",
      "price": 4256,
      "rawPrice": 4365,
      "appliedFeeBps": 250,
      "withdrawalFlatUsdCents": 0,
      "executability": 0.51,
      "updatedAt": "2026-09-25T11:20:11.402Z",
      "isStale": false,
      "reasons": [
        "unknown_executable_depth"
      ]
    },
    "spreadBps": 275,
    "locked": false,
    "crossed": false,
    "executableConfidence": 0.7,
    "reasons": [
      "unknown_executable_depth"
    ],
    "feeModelVersion": "exec-fees-v1-estimated",
    "calculatedAt": "2026-09-25T11:28:40.236Z"
  },
  "calculatedAt": "2026-09-25T11:28:40.236Z"
}
```

*The documented NBBO response. This sample is a CS2 item; a Rust response has exactly the same fields.*

## Step 3: pull price history

History works like CS2: `/v2/pricing/:marketHashName/history?game=rust` returns time buckets with `avgPrice`, `medianPrice`, `minPrice`, `maxPrice`, and the best bid and ask seen in each bucket, filtered by `from`, `to`, `listingType`, and `interval`. It needs the Pro plan. On Rust, pay attention to which field you chart.

**Node (fetch)**

```ts
import type { PriceHistoryResponse } from "@skinpricer/sdk";

const name = "Tempered AK47";
const history = await rustGet<PriceHistoryResponse>(
  "/v2/pricing/" + encodeURIComponent(name) + "/history",
  { interval: "HOUR_1" },
);

for (const bucket of history.history) {
  // On thin Rust items, chart the executable best ask, not the median.
  console.log(bucket.timestamp, bucket.bestAskCents, bucket.bestBidCents);
}
```

**curl**

```bash
curl -s "https://pricing.skinpricer.com/v2/pricing/Tempered%20AK47/history?game=rust&interval=HOUR_1" \
  -H "Authorization: ApiKey $SKINPRICER_API_KEY"
```

> **Prefer the executable side on thin Rust items:** Many Rust items are listed on only a handful of venues with widely spread asks. The aggregate `medianPrice` gives every venue equal weight, so it can sit far from any price you could actually trade at. For display and alerts, use `bestAskCents` and `bestBidCents` from history and the NBBO's `bestAsk` and `bestBid`.

## What is different about Rust data

- No wear semantics. Rust items have no float value, wear tier, paint seed, StatTrak, or souvenir variants. On Rust listings the `floatValue`, `paintSeed`, `paintIndex`, and sticker fields are always `null` or empty; see [Nulls & partial data](/api-docs/nulls).
- CS2-only endpoints stay on v1. Attribute and float bucket prices, BUFF163 buckets, recommendations, and the batch min and max price reads have no game variant.
- Plain names. The market hash name is the item's display name, so there is nothing to append for condition.
- Budgets are shared. A Rust call costs the same as a CS2 call and comes out of the same quotas, reported in the `X-RateLimit-*` headers.

## Errors and readiness

| Status | Meaning on /v2 game routes |
| --- | --- |
| 400 | Missing or invalid `game`, or invalid input such as an over-long search. |
| 404 | Unknown item in the requested game, or no pricing where the route requires it. |
| 409 | The item selector is ambiguous. Use the exact name. |
| 503 | Rust reads are temporarily disabled. Authentication and plan checks run first, so a 503 means your key and plan are fine. Retry later. |
| 401 / 403 / 429 | The same key, plan, and quota rules as every key-gated route. |

## When to reach for a different endpoint

Everything in the CS2 guides carries over to Rust once you switch to the `/v2` route and add `game=rust`. The [best bid and ask guide](/resources/cs2-best-bid-and-ask) goes deeper on reading and trusting the NBBO, [live prices](/resources/live-cs2-skin-prices) covers the full per-market snapshot, and [price history](/resources/cs2-price-history) explains intervals and bucket semantics in detail.

## Endpoints used

- [Games: CS2 & Rust](/api-docs/games.md)
- [GET /v1/pricing/:marketHashName](/api-docs/price.md)
- [GET /v1/nbbo](/api-docs/nbbo.md)
- [GET /v1/pricing/:marketHashName/history](/api-docs/history.md)
- [GET /v1/items](/api-docs/items.md)

## Related guides

- [How to get live CS2 skin prices from every marketplace](/resources/live-cs2-skin-prices.md)
- [How to find the best bid and ask for a CS2 skin across every market](/resources/cs2-best-bid-and-ask.md)
- [How to get CS2 skin price history at any interval](/resources/cs2-price-history.md)
