# cs2.sh Documentation

> Last updated: 2026-08-07. Data coverage current as of this date; see https://cs2.sh/docs/data-coverage for live coverage.

cs2.sh is a price API for the Counter-Strike 2 skin market. Real-time bid/ask prices from BUFF, Youpin, CSFloat, Skinport, Steam, and C5Game, refreshed every ~5 minutes (source-dependent), plus OHLC candles at 5m/30m/1h/1d and price history from 2023 - and to 2013 (13 years) for Steam sale history.

It includes high-frequency price history, variant item tracking, multi-year archive data, CSFloat daily sale history, liquidity rankings, and REST JSON responses.

Base URL: `https://api.cs2.sh`

---

## Documentation

---

# Introduction

High-frequency Counter-Strike 2 price history, current prices, liquidity, supply, and sale volume – with Doppler and Case Hardened variants priced individually.

cs2.sh is a price API for the Counter-Strike 2 skin market. We provide the most comprehensive real-time and historical prices from BUFF, Youpin, CSFloat, Skinport, Steam, and C5Game, refreshed every ~5 minutes. Collecting accurate pricing data is annoying. cs2.sh makes it easy to integrate in a single API, so you can spend your time building with it, rather than rebuilding it.

Base API URL: `https://api.cs2.sh`

For LLMs and coding agents! - the full docs are available at [cs2.sh/llms-full.txt](https://cs2.sh/llms-full.txt)

## Try it first

Follow the [quickstart](/docs/quickstart) to make and inspect a real response. Also, check out the [live interactive demo](/demo).

**Try free with a 2-day `developer` key** – sign up & open a ticket in our [Discord](https://discord.gg/5AJemzwBtq)!

## What makes cs2.sh different from other CS2 price APIs?

| Capability | Endpoint |
| --- | --- |
| OHLC candles at `5m`, `30m`, `1h`, and `1d`, updated continuously | [/v1/prices/history](/docs/api-reference/prices-history) |
| 3+ years of archive price history, item supply, and sale volume – with `total_supply` and `hourly_volume` on the `aggregate` source | [/v1/archive/history](/docs/api-reference/archive-history) |
| Liquidity estimates for every item and variant, computed from real price and sale-volume history on BUFF, Steam, and CSFloat | [/v1/liquidity/items](/docs/api-reference/liquidity-items) |
| Doppler, Gamma Doppler, and Case Hardened variants priced individually per source in a `variants` object | All endpoints |
| Float range price data from BUFF (e.g. `0.00 - 0.01` for an `SSG \| Dragonfire`) | [/v1/market/buff/latest](/docs/api-reference/market-buff-latest), [/v1/market/buff/history](/docs/api-reference/market-buff-history) |
| Daily CSFloat sale price and volume from 2022 onward | [/v1/archive/csfloat](/docs/api-reference/archive-csfloat) |
| Youpin sale history as hourly, 4-hour, and 12-hour series | [/v1/archive/youpin](/docs/api-reference/archive-youpin) |
| Full-depth Steam bid/ask orderbooks, and Steam median sale price and volume going back to 2013 | [/v1/market/steam/latest](/docs/api-reference/market-steam-latest), [/v1/archive/steam](/docs/api-reference/archive-steam) |
| Full item catalog – 47,000+ items with BUFF/Youpin/C5Game ids, images, wears, float ranges, and variant metadata, keyed by the same `market_hash_name` the price endpoints accept | [/v1/schema](/docs/api-reference/schema) |

See [Data Coverage](/docs/data-coverage) for sources, fields, freshness, and how far back each dataset goes.

## Core concepts

Items are identified by a canonical `market_hash_name`, for example `USP-S | Printstream (Factory New)`.

### What's the difference between ask and bid?

`ask` is the current lowest listing price; `bid` is the highest buy order. All prices are normalized to USD.

### What's the difference between updated_at and collected_at?

`updated_at` is the *marketplace* update time; `collected_at` is when cs2.sh fetched the data. Use `collected_at` for freshness checks.

## Which endpoint do I need?

| Need | Endpoint |
| --- | --- |
| Current prices for all items | [GET /v1/prices/latest](/docs/api-reference/prices-latest) |
| Current prices for specific items | [POST /v1/prices/latest](/docs/api-reference/prices-latest-post) |
| Short-medium term price history & continuous updates | [POST /v1/prices/history](/docs/api-reference/prices-history) |
| Liquidity assessments and estimated sale time | [GET /v1/liquidity/items](/docs/api-reference/liquidity-items) |
| Long-term price history, supply, and sale volume (3+ years) | [POST /v1/archive/history](/docs/api-reference/archive-history) |
| CSFloat average sale price & volume history (3+ years) | [POST /v1/archive/csfloat](/docs/api-reference/archive-csfloat) |
| Steam median sale price & volume history (10+ years) | [POST /v1/archive/steam](/docs/api-reference/archive-steam) |
| Youpin sale history | [POST /v1/archive/youpin](/docs/api-reference/archive-youpin) |
| BUFF prices for specific float or fade ranges | [GET /v1/market/buff/latest](/docs/api-reference/market-buff-latest) |
| OHLC history for BUFF float or fade ranges | [POST /v1/market/buff/history](/docs/api-reference/market-buff-history) |
| Latest full-depth Steam orderbooks | [GET /v1/market/steam/latest](/docs/api-reference/market-steam-latest) |
| Steam orderbook snapshots over time | [POST /v1/market/steam/history](/docs/api-reference/market-steam-history) |
| Full item catalog with metadata and images | [GET /v1/schema](/docs/api-reference/schema) |

## Common questions

### Is there a free tier?

Yes, we have a free 2-day `developer` key to try it out (join the [Discord](https://discord.gg/5AJemzwBtq), then open a ticket and enter the email you signed up with). Paid plans are $75/mo (latest prices) or $200/mo (all endpoints). See [Plans & Pricing](/docs/pricing).

### Which marketplaces does cs2.sh cover?

BUFF, Youpin, CSFloat, Skinport, Steam, and C5Game. See [Data Coverage](/docs/data-coverage).

### How often do prices update?

Live prices refresh every ~5 minutes, source-dependent. See [Data Coverage](/docs/data-coverage).

### How far back does price history go?

It depends on the endpoint and marketplace: high frequency price data is supported on all marketplaces from December 2025 onwards; 3+ years of archive data is supported for BUFF and Youpin; and Steam sale history goes back to 2013. See [Data Coverage](/docs/data-coverage).

### Are Doppler and Case Hardened priced separately?

Yes. Doppler, Gamma Doppler, and Case Hardened items are priced individually in a separate `variants` object, so they aren't aggregated under the base item. See [Response Format](/docs/response-format#variants).

## Support

Check these docs first as they cover endpoints, response fields, limits, plans, and source coverage. For follow-up questions or any requests, you can join our [Discord server](https://discord.gg/5AJemzwBtq).

---

# Quickstart

Make your first cs2.sh API request.

## Authentication

All `/v1` endpoints require an API key. View your key from the dashboard after subscribing to a plan, or get a free 2-day `developer` key (join our [Discord](https://discord.gg/5AJemzwBtq)).

The public API base URL is `https://api.cs2.sh`.

Every `/v1` request needs these headers:

| Header | Value | Required for |
| --- | --- | --- |
| `Authorization` | `Bearer YOUR_API_KEY` | All `/v1` endpoints |
| `Accept-Encoding` | `gzip` | All `/v1` endpoints |
| `Content-Type` | `application/json` | Recommended for POST endpoints |

`Accept-Encoding: gzip` is required for every `/v1` request. Successful responses are gzip-encoded; error responses are plain JSON.

## Your first request

Call `GET /v1/prices/latest` with your key in the `Authorization` header to fetch current prices for every tracked item. Replace `<<YOUR_API_KEY>>` with your key:

`GET https://api.cs2.sh/v1/prices/latest`

**curl**

```bash
curl https://api.cs2.sh/v1/prices/latest \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  -H "Accept-Encoding: gzip" --compressed
```

**Python**

```python
import requests

headers = {
    "Authorization": "Bearer <<YOUR_API_KEY>>",
    "Accept-Encoding": "gzip",
}

response = requests.get(
    "https://api.cs2.sh/v1/prices/latest",
    headers=headers,
)

response.raise_for_status()
data = response.json()
```

**Node**

```javascript
const headers = {
  "Authorization": "Bearer <<YOUR_API_KEY>>",
  "Accept-Encoding": "gzip",
};

const response = await fetch("https://api.cs2.sh/v1/prices/latest", { headers });

if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
```

**Go**

```go
package main

import (
    "io"
    "net/http"
)

func main() {
    req, _ := http.NewRequest("GET", "https://api.cs2.sh/v1/prices/latest", nil)
    req.Header.Set("Authorization", "Bearer <<YOUR_API_KEY>>")
    req.Header.Set("Accept-Encoding", "gzip")

    resp, err := http.DefaultClient.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    _, _ = io.ReadAll(resp.Body)
}
```

This returns every tracked item, keyed by `market_hash_name`, with one object per available marketplace (truncated below).

```json
{
  "currency": "USD",
  "items": {
    "USP-S | Printstream (Factory New)": {
      "market_hash_name": "USP-S | Printstream (Factory New)",
      "buff": {
        "updated_at": "2026-07-26T18:50:53Z",
        "collected_at": "2026-07-26T18:53:10.67Z",
        "ask": 109.72,
        "ask_volume": 463,
        "bid": 106.17,
        "bid_volume": 41
      },
      "csfloat": {
        "updated_at": "2026-07-26T18:53:05.094Z",
        "collected_at": "2026-07-26T18:53:05.134Z",
        "ask": 107.99,
        "ask_volume": 227,
        "bid": 105
      }
    }
  }
}
```

## Price history

Use `POST /v1/prices/history` for continuously-updated OHLC history, available from December 24, 2025 onward:

`POST https://api.cs2.sh/v1/prices/history`

**curl**

```bash
curl -X POST https://api.cs2.sh/v1/prices/history \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  -H "Accept-Encoding: gzip" --compressed \
  -H "Content-Type: application/json" \
  -d '{
  "items": [
    "USP-S | Printstream (Factory New)"
  ],
  "start": "2026-07-20",
  "end": "2026-07-23",
  "sources": [
    "buff",
    "csfloat"
  ],
  "interval": "1h"
}'
```

**Python**

```python
import requests

headers = {
    "Authorization": "Bearer <<YOUR_API_KEY>>",
    "Accept-Encoding": "gzip",
    "Content-Type": "application/json",
}

payload = {
    "items": ["USP-S | Printstream (Factory New)"],
    "start": "2026-07-20",
    "end": "2026-07-23",
    "sources": ["buff", "csfloat"],
    "interval": "1h",
}

response = requests.post(
    "https://api.cs2.sh/v1/prices/history",
    headers=headers,
    json=payload,
)

response.raise_for_status()
data = response.json()
```

**Node**

```javascript
const headers = {
  "Authorization": "Bearer <<YOUR_API_KEY>>",
  "Accept-Encoding": "gzip",
  "Content-Type": "application/json",
};

const response = await fetch("https://api.cs2.sh/v1/prices/history", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "items": [
      "USP-S | Printstream (Factory New)"
    ],
    "start": "2026-07-20",
    "end": "2026-07-23",
    "sources": [
      "buff",
      "csfloat"
    ],
    "interval": "1h"
  }),
});

if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
```

**Go**

```go
package main

import (
    "bytes"
    "encoding/json"
    "io"
    "net/http"
)

func main() {
    payload := map[string]any{
        "items": []any{
            "USP-S | Printstream (Factory New)",
        },
        "start": "2026-07-20",
        "end": "2026-07-23",
        "sources": []any{
            "buff",
            "csfloat",
        },
        "interval": "1h",
    }
    body, _ := json.Marshal(payload)
    req, _ := http.NewRequest("POST", "https://api.cs2.sh/v1/prices/history", bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Authorization", "Bearer <<YOUR_API_KEY>>")
    req.Header.Set("Accept-Encoding", "gzip")

    resp, err := http.DefaultClient.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    _, _ = io.ReadAll(resp.Body)
}
```

## Auth reference

### Error codes

| Status | Meaning |
| --- | --- |
| `401 unauthorized` | Missing, malformed, or invalid API key. |
| `403 forbidden` | Requested endpoint is outside your plan. |
| `429 rate_limited` | Per-second rate limit exceeded. |

See [Response Format](/docs/response-format#status-codes) for the full error model.

### Rotating your key

Rotate keys from the dashboard; rotation generates a new key and immediately invalidates the old one.

## Limits and requirements

### Required headers

`Authorization: Bearer <key>` and `Accept-Encoding: gzip` are required on every `/v1` request.

### Rate limit

10 requests per second, per user. See [Response Format](/docs/response-format#errors--limits).

### Items per request

Up to 100 items per POST request, with bodies up to 1 MiB. See [Response Format](/docs/response-format#errors--limits).

---

For LLMs and coding agents! - the full docs are available at [cs2.sh/llms-full.txt](https://cs2.sh/llms-full.txt)

---

# Data Coverage

High-frequency CS2 price history, variant items, total supply, sale volume, source fields, freshness, and historical coverage.

This page covers provided data, refresh rates, and historical data coverage for all endpoints.

## Marketplaces and fields

cs2.sh covers six marketplaces – BUFF, Youpin, CSFloat, Skinport, Steam, and C5Game.

| Source | Ask | Bid | Volume fields |
| --- | --- | --- | --- |
| `buff` | Yes | Yes | `ask_volume`, `bid_volume` |
| `youpin` | Yes | Yes | `ask_volume`, `bid_volume` |
| `csfloat` | Yes | Yes | `ask_volume`, sale volume |
| `skinport` | Yes | No | `ask_volume`, rolling `24h`, `7d`, `30d`, and `90d` statistics |
| `steam` | Yes | Yes | `ask_volume`, `bid_volume`, sale volume |
| `c5game` | Yes | Yes | `ask_volume` |

`ask` is the lowest listing price. `bid` is the highest buy order. Unavailable fields use `null`; unavailable source objects may be absent.

## Item catalog

[GET /v1/schema](/docs/api-reference/schema) provides a single schema containing all Counter-Strike 2 items. It's updated automatically when the game updates and contains ~47,500 items and ~110 collections keyed by `market_hash_name`, with rarities, wears and float ranges, marketplace ids, and item images.

## Historical coverage

Coverage is per endpoint: archive from 2023, OHLC prices since December 24, 2025, and Steam sale history since April 26, 2013.

| Endpoint | Best for | Duration | Intervals |
| --- | --- | --- | --- |
| [POST /v1/prices/history](/docs/api-reference/prices-history) | Short-term price history and continuous updates | Since December 24, 2025 | `5m`, `30m`, `1h`, `1d` |
| [POST /v1/market/buff/history](/docs/api-reference/market-buff-history) | BUFF prices by float or fade range | Since May 19, 2026 | `30m`, `1h`, `1d` |
| [POST /v1/market/steam/history](/docs/api-reference/market-steam-history) | Full-depth Steam orderbook snapshots over time | Since June 9, 2026 | `1h`, `1d` |
| [POST /v1/archive/history](/docs/api-reference/archive-history) | Long-term price history, total supply, and sale volume | Since 2023 | `1h`, `1d` |
| [POST /v1/archive/csfloat](/docs/api-reference/archive-csfloat) | CSFloat average sale price & volume history | Since 2022 | `1d` |
| [POST /v1/archive/steam](/docs/api-reference/archive-steam) | Steam median sale price & volume history | Daily since April 26, 2013; hourly since May 9, 2026 | `1h`, `1d` |
| [POST /v1/archive/youpin](/docs/api-reference/archive-youpin) | Youpin sale history | 12-hour since November 12, 2025; 4-hour since June 27, 2026; hourly since July 20, 2026 | `1h`, `4h`, `12h` |

## Refresh rates

Live prices refresh every ~5–10 minutes; archive endpoints update ~once per day.

CSFloat `bid` is present on most items, including Doppler variants, and typically updates every ~10-30 minutes depending on the item's liquidity; high liquidity items refresh more frequently. Bid history begins July 18, 2026.

`/v1/prices/history` updates continuously for short-term price history.

`/v1/market/buff/history` updates every 10 minutes.

`/v1/archive/history` updates once or twice per day for long-term price history, supply trends, and sale volume.

`/v1/archive/csfloat` updates once or twice per day for CSFloat price and sale volume.

`/v1/archive/steam` updates every ~5 hours for liquid items, and every ~16 hours for all other items.

`/v1/archive/youpin` updates ~1-2 times per day for Youpin sale prices.

## OHLC intervals

OHLC candles are recorded at `5m`, `30m`, `1h`, and `1d`.

cs2.sh uses OHLC to aggregate raw item price snapshots into fixed time buckets such as `5m`, `30m`, `1h`, and `1d`. Each bucket preserves the first, highest, lowest, and last observed prices, so it captures the shape of price movement within the interval without returning every underlying snapshot. This matters for CS2 items, where prices can move significantly within a single day and a single daily data point completely hides that.

The main history endpoint, [POST /v1/prices/history](/docs/api-reference/prices-history), returns this bucketed data. For example, a `1h` bucket combines all snapshots collected during that hour into one object with OHLC values. The result is a much smaller, easier-to-query response that still works well for any sort of time-series analysis.

## Variant pricing

Doppler phases, Gamma Doppler phases, and Case Hardened tiers are priced individually per source.

Youpin Doppler and Gamma Doppler variants carry per-phase `ask`, `bid`, and `bid_volume` on every item, with `ask_volume` on most items. Youpin Doppler prices update every ~5-15 minutes.

CSFloat Doppler prices are updated every ~10-15 minutes. Other marketplaces' Doppler prices update at the regular ~5 minute interval.

See [Response Format](/docs/response-format#variants) for the full list of `version` codes and the response shape.

---

# Response Format

Conventions used across cs2.sh responses: item maps, variants, timestamps, nulls, partial success, OHLC buckets, and the shared error and limit model.

Most responses are JSON objects with an `items` map keyed by a `market_hash_name`. All API responses are in USD. Requests are limited to 10 requests-per-second, and all POST endpoints support up to 100 items.

| Field | Meaning |
| --- | --- |
| `response_time` | When the API generated the response. |
| `currency` | Currency code, currently `USD` for public price endpoints. |
| `items` | Map of canonical item name to item data. |
| `errors` | Per-item failures returned alongside successful item data on POST endpoints. |

For source availability, high-frequency history, variant coverage, total supply, and sale-volume support, see [Data Coverage](/docs/data-coverage).

## Variants

Items with Doppler phases, Gamma Doppler phases, or Case Hardened tiers can include a `variants` object. Each variant has the same per-source shape as the base item.

```json
{
  "market_hash_name": "★ Karambit | Doppler (Factory New)",
  "buff": { "ask": 1336.26, "ask_volume": 1388, "bid": 1281.77, "bid_volume": 74 },
  "variants": {
    "Ruby": {
      "market_hash_name": "★ Karambit | Doppler (Factory New)",
      "name": "★ Karambit | Doppler (Factory New) | Ruby",
      "display_name": "Ruby",
      "version": "ruby",
      "buff": { "ask": 7671.41, "ask_volume": null, "bid": 7287.47, "bid_volume": null },
      "youpin": { "ask": 7677.31, "ask_volume": 56, "bid": null, "bid_volume": null },
      "csfloat": { "ask": 7590, "ask_volume": null, "bid": 7220 }
    }
  }
}
```

On variant entries, `market_hash_name` is the base item.

Supported `version` codes for variant items:

| Version code | Variant family | Display label |
| --- | --- | --- |
| `p1` | Doppler / Gamma Doppler | Phase 1 |
| `p2` | Doppler / Gamma Doppler | Phase 2 |
| `p3` | Doppler / Gamma Doppler | Phase 3 |
| `p4` | Doppler / Gamma Doppler | Phase 4 |
| `ruby` | Doppler | Ruby |
| `sapphire` | Doppler | Sapphire |
| `blackpearl` | Doppler | Black Pearl |
| `emerald` | Gamma Doppler | Emerald |
| `t1` | Case Hardened | Tier 1 |
| `t2` | Case Hardened | Tier 2 |
| `t3` | Case Hardened | Tier 3 |
| `t4` | Case Hardened | Tier 4 |
| `singleblue` | Case Hardened | Blue Gem |

## Timestamps

Every per-source price object can include:

| Field | Meaning |
| --- | --- |
| `updated_at` | The marketplace's own price update time. |
| `collected_at` | When cs2.sh fetched the data from that marketplace. |

## OHLC buckets

`POST /v1/prices/history` returns OHLC objects with deterministic bucket boundaries and observation timestamps.

| Field | Meaning |
| --- | --- |
| `bucket` | Start of the UTC-aligned interval. |
| `open_time` | Timestamp of the first observation inside the bucket. |
| `close_time` | Timestamp of the last observation inside the bucket. |
| `sample_count` | Number of underlying observations in the bucket. |

`ask_volume` and `bid_volume` are the last observed values in the bucket.

## Nulls and missing data

On latest-price base items, source objects are dense. `buff`, `youpin`, `csfloat`, `skinport`, `steam`, and `c5game` appear once any source has data for the item; unavailable fields are `null`.

Variant source objects are sparse. A variant includes only source objects that have data.

```json
{
  "skinport": {
    "ask": null,
    "ask_volume": null,
    "updated_at": null,
    "collected_at": null
  }
}
```

## Partial success

POST endpoints can return successful item data and item-level errors in the same response.

```json
{
  "items": {
    "USP-S | Printstream (Factory New)": {
      "market_hash_name": "USP-S | Printstream (Factory New)"
    }
  },
  "errors": [
    {
      "item": "Invalid Item Name",
      "code": "unknown_item",
      "message": "item not found"
    }
  ]
}
```

## Errors & limits

Requests are limited to 10 requests per second per user. POST endpoints accept up to 100 items per request and request bodies up to 1 MiB.

### Error format

All API errors use the same envelope:

```json
{
  "error": "error_code",
  "message": "human-readable description",
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

Some errors include a `details` object.

### Status codes

| Code | Error | Meaning |
| --- | --- | --- |
| 400 | `validation_error` | Missing field, malformed input, oversized body, or all requested items invalid. |
| 401 | `unauthorized` | Missing or invalid API key. |
| 403 | `forbidden` | Requested endpoint is outside your plan. |
| 404 | `not_found` | Unknown path, or no requested item has data in the relevant dataset. |
| 405 | `method_not_allowed` | Wrong method for the path. |
| 429 | `rate_limited` | Too many requests for the per-second rate limit. |
| 500 | `internal_error`, `database_error`, `data_processing_error` | Server-side failure. |
| 503 | `service_unavailable`, `database_unavailable` | Service or database temporarily unavailable. |
| 504 | `timeout`, `database_timeout` | Request or database timeout. |

---

# Plans & Pricing

CS2 price API plans - $75 /mo developer, $200 /mo scale.

cs2.sh has three plans. All plans include all marketplaces, unlimited requests, and a 10 requests-per-second limit.

| Plan | Price | Best for | Access |
| --- | --- | --- | --- |
| Developer | $75/mo | Current-prices | Unlimited requests to `/v1/prices/latest`, `GET /v1/market/buff/latest`, and `GET /v1/market/steam/latest` |
| Scale | $200/mo | Products that need history, archives, or liquidity data | Unlimited requests, all endpoints, including history and archive |
| Enterprise | Custom | Any custom data needs | Custom limits, custom endpoints, raw data access |

## Endpoint access

| Endpoint | Developer | Scale | Enterprise |
| --- | --- | --- | --- |
| `GET/POST /v1/prices/latest` | Yes | Yes | Yes |
| `POST /v1/prices/history` | No | Yes | Yes |
| `GET /v1/liquidity/items` | No | Yes | Yes |
| `POST /v1/archive/history` | No | Yes | Yes |
| `POST /v1/archive/csfloat` | No | Yes | Yes |
| `POST /v1/archive/steam` | No | Yes | Yes |
| `POST /v1/archive/youpin` | No | Yes | Yes |
| `GET /v1/market/buff/latest` | Yes | Yes | Yes |
| `POST /v1/market/buff/history` | No | Yes | Yes |
| `GET /v1/market/steam/latest` | Yes | Yes | Yes |
| `POST /v1/market/steam/history` | No | Yes | Yes |
| `GET /v1/schema` | Yes | Yes | Yes |

## Payment and billing

Subscriptions are typically handled through Stripe and billed monthly. Upgrades apply immediately; downgrades take effect at the next cycle. You can manage billing from the dashboard.

We also accept cryptocurrency payments (USDC / USDT) – join the [Discord](https://discord.gg/5AJemzwBtq) and open a ticket to set one up.

---

# AI & Coding Agents

cs2.sh is built for humans and AI - llms-full.txt, per-page Markdown docs, and an OpenAPI 3.1 spec for LLMs and coding agents.

cs2.sh is built for humans and AI. If you're building with an LLM or a coding agent, you can just link this page (or the resources below) and it'll have access to the full docs :).

## Full docs for AI & Agents

| Resource | URL | Contents |
| --- | --- | --- |
| `llms-full.txt` | [cs2.sh/llms-full.txt](https://cs2.sh/llms-full.txt) | The entire documentation as a single Markdown file, examples included |
| OpenAPI 3.1 | [cs2.sh/openapi.yaml](https://cs2.sh/openapi.yaml) | The machine-readable `/v1` contract: paths, parameters, schemas, and examples |

## Why the API works well for agents

- Complete documentation with response examples and API Objects
- Every endpoint uses the same `market_hash_name`, e.g. `USP-S | Printstream (Factory New)`. [GET /v1/schema](/docs/api-reference/schema) maps each name to its BUFF/Youpin/C5Game ids, wears, float ranges, variants, and images.
- Auth is two headers (`Authorization: Bearer <key>` and `Accept-Encoding: gzip`). There are no cookies, signatures, or sessions.
- Every response is an `items` map keyed by `market_hash_name`, with one object per marketplace and prices in USD. POST endpoints take up to 100 items and return per-item `errors` alongside the items that succeeded. See [Response Format](/docs/response-format).

**Try free with a 2-day `developer` key** – sign up & open a ticket in our [Discord](https://discord.gg/5AJemzwBtq)!

---

## API

---

# GET /v1/prices/latest

Current prices for all items across every supported marketplace.

Returns current bid/ask prices for all marketplaces and all items.

Prices update from marketplaces every ~5 minutes. Items with Doppler phases or Case Hardened tiers can include `variants`; see [Response Format](/docs/response-format#variants).

This snapshot includes every tracked item, so the response is large – `Accept-Encoding: gzip` is required. To fetch specific items instead, use [POST /v1/prices/latest](/docs/api-reference/prices-latest-post).

## Access

Available on all plans (Developer, Scale, Enterprise).

## Supported sources

| Source | Fields |
| --- | --- |
| `buff` | `ask`, `bid`, `ask_volume`, `bid_volume` |
| `youpin` | `ask`, `bid`, `ask_volume`, `bid_volume` |
| `csfloat` | `ask`, `bid`, `ask_volume` |
| `skinport` | `ask`, `ask_volume`, `max_ask`, `mean_ask`, `median_ask`, `24h_history`, `7d_history`, `30d_history`, `90d_history` |
| `steam` | `ask`, `bid`, `ask_volume`, `bid_volume` |
| `c5game` | `ask`, `bid`, `ask_volume` |

## Request

`GET https://api.cs2.sh/v1/prices/latest`

**curl**

```bash
curl https://api.cs2.sh/v1/prices/latest \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  -H "Accept-Encoding: gzip" --compressed
```

**Python**

```python
import requests

headers = {
    "Authorization": "Bearer <<YOUR_API_KEY>>",
    "Accept-Encoding": "gzip",
}

response = requests.get(
    "https://api.cs2.sh/v1/prices/latest",
    headers=headers,
)

response.raise_for_status()
data = response.json()
```

**Node**

```javascript
const headers = {
  "Authorization": "Bearer <<YOUR_API_KEY>>",
  "Accept-Encoding": "gzip",
};

const response = await fetch("https://api.cs2.sh/v1/prices/latest", { headers });

if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
```

**Go**

```go
package main

import (
    "io"
    "net/http"
)

func main() {
    req, _ := http.NewRequest("GET", "https://api.cs2.sh/v1/prices/latest", nil)
    req.Header.Set("Authorization", "Bearer <<YOUR_API_KEY>>")
    req.Header.Set("Accept-Encoding", "gzip")

    resp, err := http.DefaultClient.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    _, _ = io.ReadAll(resp.Body)
}
```

## Response

```json
{
  "response_time": "2026-07-26T18:54:04.041256216Z",
  "currency": "USD",
  "items": {
    "USP-S | Printstream (Factory New)": {
      "market_hash_name": "USP-S | Printstream (Factory New)",
      "buff": {
        "updated_at": "2026-07-26T18:50:53Z",
        "collected_at": "2026-07-26T18:53:10.67Z",
        "ask": 109.72,
        "ask_volume": 463,
        "bid": 106.17,
        "bid_volume": 41
      },
      "youpin": {
        "updated_at": "2026-07-26T18:52:35.85Z",
        "collected_at": "2026-07-26T18:52:41.584Z",
        "ask": 108.24,
        "ask_volume": 507,
        "bid": 107.06,
        "bid_volume": 63
      },
      "csfloat": {
        "updated_at": "2026-07-26T18:53:05.094Z",
        "collected_at": "2026-07-26T18:53:05.134Z",
        "ask": 107.99,
        "ask_volume": 227,
        "bid": 105
      },
      "skinport": {
        "updated_at": "2026-07-26T18:53:09.397Z",
        "collected_at": "2026-07-26T18:53:15.672Z",
        "ask": 115.95,
        "ask_volume": 39,
        "max_ask": 575.78,
        "mean_ask": 181.61,
        "median_ask": 156.61,
        "24h_history": {
          "price": 113.78,
          "max_price": 116.48,
          "mean_price": 115.13,
          "median_price": 115.13,
          "volume": 2
        },
        "7d_history": {
          "price": 102.41,
          "max_price": 147.72,
          "mean_price": 118.31,
          "median_price": 113.79,
          "volume": 7
        },
        "30d_history": {
          "price": 102.41,
          "max_price": 147.72,
          "mean_price": 119.16,
          "median_price": 118.57,
          "volume": 44
        },
        "90d_history": {
          "price": 96.72,
          "max_price": 210.73,
          "mean_price": 123.13,
          "median_price": 119.33,
          "volume": 149
        }
      },
      "steam": {
        "updated_at": "2026-07-26T18:52:21.42Z",
        "collected_at": "2026-07-26T18:52:54.624Z",
        "ask": 169.14,
        "ask_volume": 70,
        "bid": 155.05,
        "bid_volume": 2951
      },
      "c5game": {
        "updated_at": "2026-07-26T18:49:05.186Z",
        "collected_at": "2026-07-26T18:49:07.9Z",
        "ask": 113.56,
        "ask_volume": 141,
        "bid": 221.65
      }
    }
  }
}
```

## Response Object

### LatestPricesGetResponse

All-items snapshot. Returned by `GET /v1/prices/latest` with shared response metadata.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated |
| `currency` | `string` | Currency code (always `USD`) |
| `items` | `object` | Map of `market_hash_name` to item price data. |

## Response fields

Each item maps `market_hash_name` to one object per marketplace. Items with Doppler or Case Hardened variants nest the same shape under `variants`.

- Base item source objects are dense: `buff`, `youpin`, `csfloat`, `skinport`, `steam`, and `c5game` are present once any source has data for the item.
- Unavailable source fields are `null`.
- Variant source objects are sparse and appear only when that source has variant data.

Full schemas: [Item](/docs/api-reference/objects#item), [Variant](/docs/api-reference/objects#variant), [SkinportPriceWindow](/docs/api-reference/objects#skinportpricewindow), and the per-source types under [Latest Price Source Data](/docs/api-reference/objects#latest-price-source-data).

### Item

Price data for an item across all sources.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Steam market hash name (the canonical item identifier). |
| `buff` | `BUFFSourceData` | Price data from BUFF. |
| `youpin` | `YoupinSourceData` | Price data from Youpin898. |
| `csfloat` | `CsfloatSourceData` | Current CSFloat listing and buy-order prices. |
| `skinport` | `SkinportSourceData` | Price data from Skinport, including Skinport-supplied rolling history windows. |
| `c5game` | `C5GameSourceData` | Price data from C5Game. Ask and bid come from independent collection passes – timestamps may differ for the same item. |
| `steam` | `SteamSourceData` | Price data from the Steam Community Market. |
| `variants` | `object` | Per-variant price data for items with Doppler / Gamma Doppler phases or Case Hardened tiers. Keyed by display name. |

### Variant

A variant of an item (Doppler / Gamma Doppler phase or Case Hardened tier). `youpin` includes `ask`, `bid`, and `bid_volume` on every Doppler and Gamma Doppler phase, with `ask_volume` on most items.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Base item `market_hash_name`. Full variant name: `name`. |
| `name` | `string` | The variant's full `market_hash_name`, e.g. `★ Karambit \| Doppler (Factory New) \| Phase 1`. |
| `display_name` | `string` | Human-readable variant label (e.g. `Phase 1`, `Ruby`, `Tier 1`, `Blue Gem`). |
| `version` | `string` | Allowed: `p1`, `p2`, `p3`, `p4`, `ruby`, `sapphire`, `blackpearl`, `emerald`, `t1`, `t2`, `t3`, `t4`, `singleblue`. Stable variant code. Switch on this in client code. |
| `buff` | `BUFFSourceData` | Price data from BUFF. |
| `youpin` | `YoupinSourceData` | Price data from Youpin898. |
| `csfloat` | `CsfloatSourceData` | Current CSFloat listing and buy-order prices. |
| `skinport` | `SkinportSourceData` | Price data from Skinport, including Skinport-supplied rolling history windows. |
| `c5game` | `C5GameSourceData` | Price data from C5Game. Ask and bid come from independent collection passes – timestamps may differ for the same item. |
| `steam` | `SteamSourceData` | Price data from the Steam Community Market. |

## Latest Price Source Data

### BUFFSourceData

Price data from BUFF.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When BUFF last updated this price |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `bid` | `number` | Highest buy-order price (USD) |
| `bid_volume` | `integer` | Number of active buy orders |

### YoupinSourceData

Price data from Youpin898.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When Youpin last updated this price |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `bid` | `number` | Highest buy-order price (USD) |
| `bid_volume` | `integer` | Number of active buy orders |

### CsfloatSourceData

Current CSFloat listing and buy-order prices.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When CSFloat last updated this price |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `bid` | `number` | Highest buy-order price (USD) |

### SkinportSourceData

Price data from Skinport, including Skinport-supplied rolling history windows.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When Skinport last updated this price |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `max_ask` | `number` | Highest listing price (USD) |
| `mean_ask` | `number` | Average listing price (USD) |
| `median_ask` | `number` | Median listing price (USD) |
| `24h_history` | `SkinportPriceWindow` | Skinport-supplied rolling price window. Object is `null` when Skinport has no recent sales for the item. |
| `7d_history` | `SkinportPriceWindow` | Skinport-supplied rolling price window. Object is `null` when Skinport has no recent sales for the item. |
| `30d_history` | `SkinportPriceWindow` | Skinport-supplied rolling price window. Object is `null` when Skinport has no recent sales for the item. |
| `90d_history` | `SkinportPriceWindow` | Skinport-supplied rolling price window. Object is `null` when Skinport has no recent sales for the item. |

### SteamSourceData

Price data from the Steam Community Market.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When the upstream price was last updated |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `bid` | `number` | Highest buy-order price (USD) |
| `bid_volume` | `integer` | Number of active buy orders |

### C5GameSourceData

Price data from C5Game. Ask and bid come from independent collection passes – timestamps may differ for the same item.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When C5Game last updated this price |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `bid` | `number` | Highest buy-order price (USD) |

### SkinportPriceWindow

Skinport-supplied rolling price window. Object is `null` when Skinport has no recent sales for the item.

| Field | Type | Description |
| --- | --- | --- |
| `price` | `number` | Last sale price (USD) within the window |
| `max_price` | `number` | Highest sale price (USD) within the window |
| `mean_price` | `number` | Average sale price (USD) within the window |
| `median_price` | `number` | Median sale price (USD) within the window |
| `volume` | `integer` | Number of sales within the window |

## Errors

This endpoint returns the full snapshot.

| Status | When |
| --- | --- |
| `401` / `403` | Missing key, invalid key, or plan access. |
| `429` | Rate-limited. |
| `503` / `5xx` | Snapshot unavailable or server-side issue. |

---

# POST /v1/prices/latest

Current prices for up to 100 specific items in one request.

Returns current bid/ask prices for up to 100 specific items for all marketplaces.

Prices update from marketplaces every ~5 minutes. Items with Doppler phases or Case Hardened tiers include a `variants` response; see [Response Format](/docs/response-format#variants).

## Access

Available on all plans (Developer, Scale, Enterprise).

## Supported sources

| Source | Fields |
| --- | --- |
| `buff` | `ask`, `bid`, `ask_volume`, `bid_volume` |
| `youpin` | `ask`, `bid`, `ask_volume`, `bid_volume` |
| `csfloat` | `ask`, `bid`, `ask_volume` |
| `skinport` | `ask`, `ask_volume`, `max_ask`, `mean_ask`, `median_ask`, `24h_history`, `7d_history`, `30d_history`, `90d_history` |
| `steam` | `ask`, `bid`, `ask_volume`, `bid_volume` |
| `c5game` | `ask`, `bid`, `ask_volume` |

## Request

`POST https://api.cs2.sh/v1/prices/latest`

**curl**

```bash
curl -X POST https://api.cs2.sh/v1/prices/latest \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  -H "Accept-Encoding: gzip" --compressed \
  -H "Content-Type: application/json" \
  -d '{
  "items": [
    "USP-S | Printstream (Factory New)",
    "★ Karambit | Doppler (Factory New)"
  ]
}'
```

**Python**

```python
import requests

headers = {
    "Authorization": "Bearer <<YOUR_API_KEY>>",
    "Accept-Encoding": "gzip",
    "Content-Type": "application/json",
}

payload = {
    "items": ["USP-S | Printstream (Factory New)", "★ Karambit | Doppler (Factory New)"],
}

response = requests.post(
    "https://api.cs2.sh/v1/prices/latest",
    headers=headers,
    json=payload,
)

response.raise_for_status()
data = response.json()
```

**Node**

```javascript
const headers = {
  "Authorization": "Bearer <<YOUR_API_KEY>>",
  "Accept-Encoding": "gzip",
  "Content-Type": "application/json",
};

const response = await fetch("https://api.cs2.sh/v1/prices/latest", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "items": [
      "USP-S | Printstream (Factory New)",
      "★ Karambit | Doppler (Factory New)"
    ]
  }),
});

if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
```

**Go**

```go
package main

import (
    "bytes"
    "encoding/json"
    "io"
    "net/http"
)

func main() {
    payload := map[string]any{
        "items": []any{
            "USP-S | Printstream (Factory New)",
            "★ Karambit | Doppler (Factory New)",
        },
    }
    body, _ := json.Marshal(payload)
    req, _ := http.NewRequest("POST", "https://api.cs2.sh/v1/prices/latest", bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Authorization", "Bearer <<YOUR_API_KEY>>")
    req.Header.Set("Accept-Encoding", "gzip")

    resp, err := http.DefaultClient.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    _, _ = io.ReadAll(resp.Body)
}
```

## Parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `items` | `string[]` | Yes | List of market_hash_name values (max 100) |

## Response

```json
{
  "response_time": "2026-07-26T18:54:14.07101243Z",
  "currency": "USD",
  "items": {
    "USP-S | Printstream (Factory New)": {
      "market_hash_name": "USP-S | Printstream (Factory New)",
      "buff": {
        "updated_at": "2026-07-26T18:50:53Z",
        "collected_at": "2026-07-26T18:53:10.67Z",
        "ask": 109.72,
        "ask_volume": 463,
        "bid": 106.17,
        "bid_volume": 41
      },
      "youpin": {
        "updated_at": "2026-07-26T18:52:35.85Z",
        "collected_at": "2026-07-26T18:52:41.584Z",
        "ask": 108.24,
        "ask_volume": 507,
        "bid": 107.06,
        "bid_volume": 63
      },
      "csfloat": {
        "updated_at": "2026-07-26T18:53:05.094Z",
        "collected_at": "2026-07-26T18:53:05.134Z",
        "ask": 107.99,
        "ask_volume": 227,
        "bid": 105
      },
      "skinport": {
        "updated_at": "2026-07-26T18:53:09.397Z",
        "collected_at": "2026-07-26T18:53:15.672Z",
        "ask": 115.95,
        "ask_volume": 39,
        "max_ask": 575.78,
        "mean_ask": 181.61,
        "median_ask": 156.61,
        "24h_history": {
          "price": 113.78,
          "max_price": 116.48,
          "mean_price": 115.13,
          "median_price": 115.13,
          "volume": 2
        },
        "7d_history": {
          "price": 102.41,
          "max_price": 147.72,
          "mean_price": 118.31,
          "median_price": 113.79,
          "volume": 7
        },
        "30d_history": {
          "price": 102.41,
          "max_price": 147.72,
          "mean_price": 119.16,
          "median_price": 118.57,
          "volume": 44
        },
        "90d_history": {
          "price": 96.72,
          "max_price": 210.73,
          "mean_price": 123.13,
          "median_price": 119.33,
          "volume": 149
        }
      },
      "steam": {
        "updated_at": "2026-07-26T18:52:21.42Z",
        "collected_at": "2026-07-26T18:52:54.624Z",
        "ask": 169.14,
        "ask_volume": 70,
        "bid": 155.05,
        "bid_volume": 2951
      },
      "c5game": {
        "updated_at": "2026-07-26T18:49:05.186Z",
        "collected_at": "2026-07-26T18:49:07.9Z",
        "ask": 113.56,
        "ask_volume": 141,
        "bid": 221.65
      }
    },
    "★ Karambit | Doppler (Factory New)": {
      "market_hash_name": "★ Karambit | Doppler (Factory New)",
      "buff": {
        "updated_at": "2026-07-26T18:50:31Z",
        "collected_at": "2026-07-26T18:53:10.67Z",
        "ask": 1336.26,
        "ask_volume": 1388,
        "bid": 1281.77,
        "bid_volume": 74
      },
      "youpin": {
        "updated_at": "2026-07-26T18:53:02.688Z",
        "collected_at": "2026-07-26T18:53:27.921Z",
        "ask": 1320.68,
        "ask_volume": 1492,
        "bid": 1308.35,
        "bid_volume": 30
      },
      "csfloat": {
        "updated_at": "2026-07-26T18:53:05.094Z",
        "collected_at": "2026-07-26T18:53:05.134Z",
        "ask": 1282.77,
        "ask_volume": 872,
        "bid": null
      },
      "variants": {
        "Phase 2": {
          "market_hash_name": "★ Karambit | Doppler (Factory New)",
          "name": "★ Karambit | Doppler (Factory New) | Phase 2",
          "display_name": "Phase 2",
          "version": "p2",
          "buff": {
            "updated_at": "2026-07-26T18:50:31Z",
            "collected_at": "2026-07-26T18:53:10.67Z",
            "ask": 1964,
            "ask_volume": null,
            "bid": 1890.16,
            "bid_volume": null
          },
          "youpin": {
            "updated_at": "2026-07-26T18:53:02.688Z",
            "collected_at": "2026-07-26T18:53:27.921Z",
            "ask": 1941.7,
            "ask_volume": 376,
            "bid": 1931.51,
            "bid_volume": 51
          },
          "csfloat": {
            "updated_at": "2026-07-26T18:53:30.139Z",
            "collected_at": "2026-07-26T18:53:30.141Z",
            "ask": 1904.99,
            "ask_volume": null,
            "bid": 1850
          },
          "c5game": {
            "updated_at": "2026-07-26T18:51:54.01Z",
            "collected_at": "2026-07-26T18:53:47.628Z",
            "ask": 1938.71,
            "ask_volume": 58,
            "bid": 1882.78
          }
        },
        "Ruby": {
          "market_hash_name": "★ Karambit | Doppler (Factory New)",
          "name": "★ Karambit | Doppler (Factory New) | Ruby",
          "display_name": "Ruby",
          "version": "ruby",
          "buff": {
            "updated_at": "2026-07-26T18:50:31Z",
            "collected_at": "2026-07-26T18:53:10.67Z",
            "ask": 7671.41,
            "ask_volume": null,
            "bid": 7287.47,
            "bid_volume": null
          },
          "youpin": {
            "updated_at": "2026-07-26T18:53:02.688Z",
            "collected_at": "2026-07-26T18:53:27.921Z",
            "ask": 7677.31,
            "ask_volume": 56,
            "bid": null,
            "bid_volume": null
          },
          "csfloat": {
            "updated_at": "2026-07-26T18:50:03.689Z",
            "collected_at": "2026-07-26T18:50:34.993Z",
            "ask": 7590,
            "ask_volume": null,
            "bid": 7220
          },
          "c5game": {
            "updated_at": "2026-07-26T18:51:55.243Z",
            "collected_at": "2026-07-26T18:53:47.628Z",
            "ask": 8231.08,
            "ask_volume": 13,
            "bid": 6202.1
          }
        }
      }
    }
  }
}
```

## Response Object

### LatestPricesPostResponse

Filtered per-item snapshot. Returned by `POST /v1/prices/latest` – includes per-item `errors`.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated |
| `currency` | `string` | Currency code (always `USD`) |
| `items` | `object` | Map of `market_hash_name` to item price data, filtered to the requested items. |
| `errors` | `ItemError[]` | Per-item failures alongside successful results (partial success). |

## Response fields

Each item maps `market_hash_name` to one object per marketplace. Items with Doppler or Case Hardened variants nest the same shape under `variants`.

- Base item source objects are dense: `buff`, `youpin`, `csfloat`, `skinport`, `steam`, and `c5game` are present once any source has data for the item.
- Unavailable source fields are `null`.
- Variant source objects are sparse and appear only when that source has variant data.

Full schemas: [Item](/docs/api-reference/objects#item), [Variant](/docs/api-reference/objects#variant), [SkinportPriceWindow](/docs/api-reference/objects#skinportpricewindow), and the per-source types under [Latest Price Source Data](/docs/api-reference/objects#latest-price-source-data).

### Item

Price data for an item across all sources.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Steam market hash name (the canonical item identifier). |
| `buff` | `BUFFSourceData` | Price data from BUFF. |
| `youpin` | `YoupinSourceData` | Price data from Youpin898. |
| `csfloat` | `CsfloatSourceData` | Current CSFloat listing and buy-order prices. |
| `skinport` | `SkinportSourceData` | Price data from Skinport, including Skinport-supplied rolling history windows. |
| `c5game` | `C5GameSourceData` | Price data from C5Game. Ask and bid come from independent collection passes – timestamps may differ for the same item. |
| `steam` | `SteamSourceData` | Price data from the Steam Community Market. |
| `variants` | `object` | Per-variant price data for items with Doppler / Gamma Doppler phases or Case Hardened tiers. Keyed by display name. |

### Variant

A variant of an item (Doppler / Gamma Doppler phase or Case Hardened tier). `youpin` includes `ask`, `bid`, and `bid_volume` on every Doppler and Gamma Doppler phase, with `ask_volume` on most items.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Base item `market_hash_name`. Full variant name: `name`. |
| `name` | `string` | The variant's full `market_hash_name`, e.g. `★ Karambit \| Doppler (Factory New) \| Phase 1`. |
| `display_name` | `string` | Human-readable variant label (e.g. `Phase 1`, `Ruby`, `Tier 1`, `Blue Gem`). |
| `version` | `string` | Allowed: `p1`, `p2`, `p3`, `p4`, `ruby`, `sapphire`, `blackpearl`, `emerald`, `t1`, `t2`, `t3`, `t4`, `singleblue`. Stable variant code. Switch on this in client code. |
| `buff` | `BUFFSourceData` | Price data from BUFF. |
| `youpin` | `YoupinSourceData` | Price data from Youpin898. |
| `csfloat` | `CsfloatSourceData` | Current CSFloat listing and buy-order prices. |
| `skinport` | `SkinportSourceData` | Price data from Skinport, including Skinport-supplied rolling history windows. |
| `c5game` | `C5GameSourceData` | Price data from C5Game. Ask and bid come from independent collection passes – timestamps may differ for the same item. |
| `steam` | `SteamSourceData` | Price data from the Steam Community Market. |

## Latest Price Source Data

### BUFFSourceData

Price data from BUFF.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When BUFF last updated this price |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `bid` | `number` | Highest buy-order price (USD) |
| `bid_volume` | `integer` | Number of active buy orders |

### YoupinSourceData

Price data from Youpin898.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When Youpin last updated this price |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `bid` | `number` | Highest buy-order price (USD) |
| `bid_volume` | `integer` | Number of active buy orders |

### CsfloatSourceData

Current CSFloat listing and buy-order prices.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When CSFloat last updated this price |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `bid` | `number` | Highest buy-order price (USD) |

### SkinportSourceData

Price data from Skinport, including Skinport-supplied rolling history windows.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When Skinport last updated this price |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `max_ask` | `number` | Highest listing price (USD) |
| `mean_ask` | `number` | Average listing price (USD) |
| `median_ask` | `number` | Median listing price (USD) |
| `24h_history` | `SkinportPriceWindow` | Skinport-supplied rolling price window. Object is `null` when Skinport has no recent sales for the item. |
| `7d_history` | `SkinportPriceWindow` | Skinport-supplied rolling price window. Object is `null` when Skinport has no recent sales for the item. |
| `30d_history` | `SkinportPriceWindow` | Skinport-supplied rolling price window. Object is `null` when Skinport has no recent sales for the item. |
| `90d_history` | `SkinportPriceWindow` | Skinport-supplied rolling price window. Object is `null` when Skinport has no recent sales for the item. |

### SteamSourceData

Price data from the Steam Community Market.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When the upstream price was last updated |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `bid` | `number` | Highest buy-order price (USD) |
| `bid_volume` | `integer` | Number of active buy orders |

### C5GameSourceData

Price data from C5Game. Ask and bid come from independent collection passes – timestamps may differ for the same item.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When C5Game last updated this price |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `bid` | `number` | Highest buy-order price (USD) |

### SkinportPriceWindow

Skinport-supplied rolling price window. Object is `null` when Skinport has no recent sales for the item.

| Field | Type | Description |
| --- | --- | --- |
| `price` | `number` | Last sale price (USD) within the window |
| `max_price` | `number` | Highest sale price (USD) within the window |
| `mean_price` | `number` | Average sale price (USD) within the window |
| `median_price` | `number` | Median sale price (USD) within the window |
| `volume` | `integer` | Number of sales within the window |

## Errors

| Status | When |
| --- | --- |
| `400 validation_error` | The request body or query failed validation (e.g. bad JSON, missing `items`/`start`, over 100 items, or a bad `interval` or date range). |
| `404 not_found` | No requested valid item is present in the latest snapshot. |
| `401` / `403` | Missing key, invalid key, or plan access. |
| `429` | Rate-limited. |
| `503` / `5xx` | Snapshot unavailable or server-side issue. |

When some items resolve and others don't, the request still returns `200` with the resolved items plus an `errors[]` array – each entry is an [ItemError](/docs/api-reference/objects#itemerror) with a `code` of `unknown_item`, `invalid_format`, or `not_in_cache`.

---

# POST /v1/prices/history

Continuously updated OHLC price history for CS2 items since December 24, 2025.

Returns continuously updated OHLC price history. Use this endpoint for short-medium term price history. Data begins on December 24, 2025. Prices update every ~5 minutes - data for this endpoint is the same as `prices/latest`. Max 100 items per request.

Items with Doppler phases or Case Hardened tiers include a `variants` response; see [Response Format](/docs/response-format#variants).

## Access

Requires a Scale or Enterprise API key.

## Supported intervals

| Interval | Max range |
| --- | --- |
| `5m` | 14 days |
| `30m` | 90 days |
| `1h` | 365 days |
| `1d` | Unlimited |

## Supported sources

| Source | Fields |
| --- | --- |
| `buff` | `ask`, `bid`, `ask_volume`, `bid_volume` |
| `youpin` | `ask`, `bid`, `ask_volume`, `bid_volume` |
| `csfloat` | `ask`, `bid`, `ask_volume` |
| `skinport` | `ask`, `ask_volume` |
| `steam` | `ask`, `bid`, `ask_volume`, `bid_volume` |
| `c5game` | `ask`, `bid`, `ask_volume` |

Default source selection: all sources.

`bucket` is the UTC interval boundary. `open_time` and `close_time` are the actual first and last observations inside the bucket; see [Response Format](/docs/response-format#ohlc-buckets).

## Request

`POST https://api.cs2.sh/v1/prices/history`

**curl**

```bash
curl -X POST https://api.cs2.sh/v1/prices/history \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  -H "Accept-Encoding: gzip" --compressed \
  -H "Content-Type: application/json" \
  -d '{
  "items": [
    "USP-S | Printstream (Factory New)"
  ],
  "start": "2026-07-20",
  "end": "2026-07-23",
  "sources": [
    "buff",
    "csfloat"
  ],
  "interval": "1h"
}'
```

**Python**

```python
import requests

headers = {
    "Authorization": "Bearer <<YOUR_API_KEY>>",
    "Accept-Encoding": "gzip",
    "Content-Type": "application/json",
}

payload = {
    "items": ["USP-S | Printstream (Factory New)"],
    "start": "2026-07-20",
    "end": "2026-07-23",
    "sources": ["buff", "csfloat"],
    "interval": "1h",
}

response = requests.post(
    "https://api.cs2.sh/v1/prices/history",
    headers=headers,
    json=payload,
)

response.raise_for_status()
data = response.json()
```

**Node**

```javascript
const headers = {
  "Authorization": "Bearer <<YOUR_API_KEY>>",
  "Accept-Encoding": "gzip",
  "Content-Type": "application/json",
};

const response = await fetch("https://api.cs2.sh/v1/prices/history", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "items": [
      "USP-S | Printstream (Factory New)"
    ],
    "start": "2026-07-20",
    "end": "2026-07-23",
    "sources": [
      "buff",
      "csfloat"
    ],
    "interval": "1h"
  }),
});

if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
```

**Go**

```go
package main

import (
    "bytes"
    "encoding/json"
    "io"
    "net/http"
)

func main() {
    payload := map[string]any{
        "items": []any{
            "USP-S | Printstream (Factory New)",
        },
        "start": "2026-07-20",
        "end": "2026-07-23",
        "sources": []any{
            "buff",
            "csfloat",
        },
        "interval": "1h",
    }
    body, _ := json.Marshal(payload)
    req, _ := http.NewRequest("POST", "https://api.cs2.sh/v1/prices/history", bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Authorization", "Bearer <<YOUR_API_KEY>>")
    req.Header.Set("Accept-Encoding", "gzip")

    resp, err := http.DefaultClient.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    _, _ = io.ReadAll(resp.Body)
}
```

## Parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `items` | `string[]` | Yes | List of market_hash_name values (max 100) |
| `start` | `string` | Yes | Start date (YYYY-MM-DD or RFC3339) |
| `end` | `string` | No | End date (YYYY-MM-DD or RFC3339). Default: now |
| `sources` | `string[]` | No | Filter to specific sources. Default: all sources |
| `interval` | `string` | No | Default: `5m`. Allowed: `5m`, `30m`, `1h`, `1d`. Aggregation interval |

## Response

```json
{
  "response_time": "2026-07-26T18:54:17.003186292Z",
  "currency": "USD",
  "start": "2026-07-20T00:00:00Z",
  "end": "2026-07-23T00:00:00Z",
  "interval": "1h",
  "items": {
    "USP-S | Printstream (Factory New)": {
      "market_hash_name": "USP-S | Printstream (Factory New)",
      "count": 72,
      "data": [
        {
          "bucket": "2026-07-20T00:00:00Z",
          "buff": {
            "open_ask": 115.16,
            "high_ask": 115.16,
            "low_ask": 115.16,
            "close_ask": 115.16,
            "ask_volume": 466,
            "open_bid": 112.21,
            "high_bid": 112.21,
            "low_bid": 112.21,
            "close_bid": 112.21,
            "bid_volume": 42,
            "sample_count": 75,
            "open_time": "2026-07-20T00:00:51Z",
            "close_time": "2026-07-20T00:58:51Z"
          },
          "youpin": {
            "open_ask": 113.54,
            "high_ask": 113.54,
            "low_ask": 113.54,
            "close_ask": 113.54,
            "ask_volume": 505,
            "open_bid": 112.5,
            "high_bid": 112.5,
            "low_bid": 112.5,
            "close_bid": 112.5,
            "bid_volume": 64,
            "sample_count": 12,
            "open_time": "2026-07-20T00:04:07Z",
            "close_time": "2026-07-20T00:58:07Z"
          },
          "csfloat": {
            "open_ask": 109.85,
            "high_ask": 109.85,
            "low_ask": 109.85,
            "close_ask": 109.85,
            "ask_volume": 229,
            "open_bid": 107,
            "high_bid": 107,
            "low_bid": 107,
            "close_bid": 107,
            "sample_count": 60,
            "open_time": "2026-07-20T00:00:25.313Z",
            "close_time": "2026-07-20T00:44:01.71Z"
          },
          "skinport": {
            "open_ask": 122.71,
            "high_ask": 122.71,
            "low_ask": 122.71,
            "close_ask": 122.71,
            "ask_volume": 43,
            "sample_count": 60,
            "open_time": "2026-07-20T00:00:29.985Z",
            "close_time": "2026-07-20T00:59:29.996Z"
          },
          "steam": {
            "open_ask": 161,
            "high_ask": 161.62,
            "low_ask": 161,
            "close_ask": 161.62,
            "ask_volume": 69,
            "open_bid": 155.43,
            "high_bid": 155.43,
            "low_bid": 155.43,
            "close_bid": 155.43,
            "bid_volume": 2940,
            "sample_count": 9,
            "open_time": "2026-07-20T00:02:52.014Z",
            "close_time": "2026-07-20T00:54:22.006Z"
          },
          "c5game": {
            "open_ask": 116.34,
            "high_ask": 116.34,
            "low_ask": 116.19,
            "close_ask": 116.19,
            "ask_volume": 147,
            "open_bid": 232.98,
            "high_bid": 232.98,
            "low_bid": 232.98,
            "close_bid": 232.98,
            "sample_count": 12,
            "open_time": "2026-07-20T00:02:49.997Z",
            "close_time": "2026-07-20T00:37:50.106Z"
          }
        }
      ]
    }
  }
}
```

## Response Object

### HistoryResponse

Response shape for `POST /v1/prices/history`.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated. |
| `currency` | `string` | Currency code (always `USD`). |
| `start` | `string (date-time)` | Effective start of the queried range, floored to the interval boundary. |
| `end` | `string (date-time)` | Effective end of the queried range, ceiled to the interval boundary. Exclusive. |
| `interval` | `string` | Allowed: `5m`, `30m`, `1h`, `1d`. OHLC bucket size. |
| `items` | `object` | Map of `market_hash_name` to OHLC time-series. |
| `errors` | `ItemError[]` | Per-item failures alongside successful results (partial success). |

## Response fields

Each item holds `count` (buckets with data) and a `data[]` array of OHLC buckets. `bucket` is the UTC-aligned interval boundary; each per-source object carries OHLC values plus the real observation window (`open_time`/`close_time`) and `sample_count`. `csfloat` carries ask and bid OHLC without `bid_volume`; `skinport` is ask-only. Variants nest under `variants`.

- `bucket` is present on every history bucket.
- Per-source objects appear only when that source has data in the bucket.
- Valid requested items with no buckets in the requested range are omitted from `items`.

Full schemas: [HistoryItem](/docs/api-reference/objects#historyitem), [HistoryBucket](/docs/api-reference/objects#historybucket), and the per-source types under [OHLC Source Data](/docs/api-reference/objects#ohlc-source-data).

### HistoryItem

OHLC time-series for a single item.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Steam market hash name (the canonical item identifier). |
| `count` | `integer` | Number of buckets with data |
| `data` | `HistoryBucket[]` | OHLC buckets in chronological order. |
| `variants` | `object` | Per-variant OHLC time-series for items with Doppler / Gamma Doppler phases or Case Hardened tiers. Keyed by display name. |

### HistoryBucket

A single OHLC time bucket. `bucket` is the interval boundary (UTC-aligned, deterministic); `open_time`/`close_time` on each per-source object are the actual first/last observation timestamps inside it.

| Field | Type | Description |
| --- | --- | --- |
| `bucket` | `string (date-time)` | Start of the time bucket. UTC-aligned to the interval boundary (e.g. `2026-01-08T19:00:00Z` for an `1h` bucket). Deterministic. |
| `buff` | `BUFFOHLCSourceData` | OHLC bucket of BUFF prices. |
| `youpin` | `YoupinOHLCSourceData` | OHLC bucket of Youpin prices. |
| `csfloat` | `CsfloatOHLCSourceData` | OHLC bucket of CSFloat ask and bid prices. |
| `skinport` | `SkinportOHLCSourceData` | OHLC bucket of Skinport ask prices. |
| `c5game` | `C5GameOHLCSourceData` | OHLC bucket of C5Game ask and bid prices. |
| `steam` | `SteamOHLCSourceData` | OHLC bucket of Steam Community Market ask and bid prices. |

## OHLC Source Data

### BUFFOHLCSourceData

OHLC bucket of BUFF prices.

| Field | Type | Description |
| --- | --- | --- |
| `open_ask` | `number` | First ask price in the bucket |
| `high_ask` | `number` | Highest ask price in the bucket |
| `low_ask` | `number` | Lowest ask price in the bucket |
| `close_ask` | `number` | Last ask price in the bucket |
| `ask_volume` | `integer` | Last observed ask volume in the bucket |
| `open_bid` | `number` | First bid price in the bucket |
| `high_bid` | `number` | Highest bid price in the bucket |
| `low_bid` | `number` | Lowest bid price in the bucket |
| `close_bid` | `number` | Last bid price in the bucket |
| `bid_volume` | `integer` | Last observed bid volume in the bucket |
| `sample_count` | `integer` | Number of underlying 5-minute observations aggregated into this bucket |
| `open_time` | `string (date-time)` | Timestamp of the first observation inside this bucket. Distinct from `bucket` (the interval boundary). |
| `close_time` | `string (date-time)` | Timestamp of the last observation inside this bucket. Distinct from `bucket` (the interval boundary). |

### YoupinOHLCSourceData

OHLC bucket of Youpin prices.

| Field | Type | Description |
| --- | --- | --- |
| `open_ask` | `number` | First ask price in the bucket |
| `high_ask` | `number` | Highest ask price in the bucket |
| `low_ask` | `number` | Lowest ask price in the bucket |
| `close_ask` | `number` | Last ask price in the bucket |
| `ask_volume` | `integer` | Last observed ask volume in the bucket |
| `open_bid` | `number` | First bid price in the bucket |
| `high_bid` | `number` | Highest bid price in the bucket |
| `low_bid` | `number` | Lowest bid price in the bucket |
| `close_bid` | `number` | Last bid price in the bucket |
| `bid_volume` | `integer` | Last observed bid volume in the bucket |
| `sample_count` | `integer` | Number of underlying 5-minute observations aggregated into this bucket |
| `open_time` | `string (date-time)` | Timestamp of the first observation inside this bucket. Distinct from `bucket` (the interval boundary). |
| `close_time` | `string (date-time)` | Timestamp of the last observation inside this bucket. Distinct from `bucket` (the interval boundary). |

### CsfloatOHLCSourceData

OHLC bucket of CSFloat ask and bid prices.

| Field | Type | Description |
| --- | --- | --- |
| `open_ask` | `number` | First ask price in the bucket |
| `high_ask` | `number` | Highest ask price in the bucket |
| `low_ask` | `number` | Lowest ask price in the bucket |
| `close_ask` | `number` | Last ask price in the bucket |
| `ask_volume` | `integer` | Last observed ask volume in the bucket |
| `open_bid` | `number` | First bid price in the bucket |
| `high_bid` | `number` | Highest bid price in the bucket |
| `low_bid` | `number` | Lowest bid price in the bucket |
| `close_bid` | `number` | Last bid price in the bucket |
| `sample_count` | `integer` | Number of underlying 5-minute observations aggregated into this bucket |
| `open_time` | `string (date-time)` | Timestamp of the first observation inside this bucket. Distinct from `bucket` (the interval boundary). |
| `close_time` | `string (date-time)` | Timestamp of the last observation inside this bucket. Distinct from `bucket` (the interval boundary). |

### SkinportOHLCSourceData

OHLC bucket of Skinport ask prices.

| Field | Type | Description |
| --- | --- | --- |
| `open_ask` | `number` | First ask price in the bucket |
| `high_ask` | `number` | Highest ask price in the bucket |
| `low_ask` | `number` | Lowest ask price in the bucket |
| `close_ask` | `number` | Last ask price in the bucket |
| `ask_volume` | `integer` | Last observed ask volume in the bucket |
| `sample_count` | `integer` | Number of underlying 5-minute observations aggregated into this bucket |
| `open_time` | `string (date-time)` | Timestamp of the first observation inside this bucket. Distinct from `bucket` (the interval boundary). |
| `close_time` | `string (date-time)` | Timestamp of the last observation inside this bucket. Distinct from `bucket` (the interval boundary). |

### SteamOHLCSourceData

OHLC bucket of Steam Community Market ask and bid prices.

| Field | Type | Description |
| --- | --- | --- |
| `open_ask` | `number` | First ask price in the bucket |
| `high_ask` | `number` | Highest ask price in the bucket |
| `low_ask` | `number` | Lowest ask price in the bucket |
| `close_ask` | `number` | Last ask price in the bucket |
| `ask_volume` | `integer` | Last observed ask volume in the bucket |
| `open_bid` | `number` | First bid price in the bucket |
| `high_bid` | `number` | Highest bid price in the bucket |
| `low_bid` | `number` | Lowest bid price in the bucket |
| `close_bid` | `number` | Last bid price in the bucket |
| `bid_volume` | `integer` | Last observed bid volume in the bucket |
| `sample_count` | `integer` | Number of underlying 5-minute observations aggregated into this bucket |
| `open_time` | `string (date-time)` | Timestamp of the first observation inside this bucket. Distinct from `bucket` (the interval boundary). |
| `close_time` | `string (date-time)` | Timestamp of the last observation inside this bucket. Distinct from `bucket` (the interval boundary). |

### C5GameOHLCSourceData

OHLC bucket of C5Game ask and bid prices.

| Field | Type | Description |
| --- | --- | --- |
| `open_ask` | `number` | First ask price in the bucket |
| `high_ask` | `number` | Highest ask price in the bucket |
| `low_ask` | `number` | Lowest ask price in the bucket |
| `close_ask` | `number` | Last ask price in the bucket |
| `ask_volume` | `integer` | Last observed ask volume in the bucket |
| `open_bid` | `number` | First bid price in the bucket |
| `high_bid` | `number` | Highest bid price in the bucket |
| `low_bid` | `number` | Lowest bid price in the bucket |
| `close_bid` | `number` | Last bid price in the bucket |
| `sample_count` | `integer` | Number of underlying 5-minute observations aggregated into this bucket |
| `open_time` | `string (date-time)` | Timestamp of the first observation inside this bucket. Distinct from `bucket` (the interval boundary). |
| `close_time` | `string (date-time)` | Timestamp of the last observation inside this bucket. Distinct from `bucket` (the interval boundary). |

## Errors

| Status | When |
| --- | --- |
| `400 validation_error` | The request body or query failed validation (e.g. bad JSON, missing `items`/`start`, over 100 items, or a bad `interval` or date range). |
| `401` / `403` | Missing key, invalid key, or plan access. |
| `429` | Rate-limited. |
| `5xx` | Server-side issue. |

When some items resolve and others don't, the request still returns `200` with the resolved items plus an `errors[]` array. `errors[]` is for invalid or unresolved item names, not for valid items with no buckets.

---

# GET /v1/liquidity/items

Daily liquidity buckets and estimated sale times for every item.

Returns the latest liquidity assessment (ranging from `extremely_illiquid` to `extremely_liquid`) and estimated sale time for all items.

This endpoint is designed for accurate liquidity assessments and updates daily.

## Access

Requires a Scale or Enterprise API key.

## Supported sources

Liquidity is computed from real sale and price history on these sources:

| Source | Used for |
| --- | --- |
| `buff` | Sale volume and price history |
| `steam` | Sale volume and price history |
| `csfloat` | Completed-sale volume and price history |

## What do the liquidity buckets mean?

`liquidity` returns one of these buckets:

| Bucket | Meaning |
| --- | --- |
| `unknown` | Too few recent sales to classify. |
| `extremely_illiquid` | Almost no sales. |
| `very_illiquid` | Very low sale volume. |
| `illiquid` | Low sale volume. |
| `moderate` | Moderate sale volume. |
| `liquid` | Consistent sale volume. |
| `very_liquid` | High sale volume. |
| `extremely_liquid` | Very high sale volume; among the most-traded items. |

## How is liquidity calculated?

Liquidity is scored from daily sale volume and traded value (`price * volume`) over rolling 30- and 90-day windows, weighted toward more recent activity. Each exact `market_hash_name` is assigned a bucket from this recent sale history. Variants are scored independently from their base item. Items with very sparse recent sales are placed in more conservative buckets. Liquidity is recomputed daily.

Sale time is an estimate derived from sale volume frequency. It assumes a competitive listing price.

| Sale time, assuming competitive price | `estimated_sale_time` |
| --- | --- |
| `<= 1 hour` | `under 1 hour` |
| `<= 2 hours` | `1 - 2 hours` |
| `<= 6 hours` | `2 - 6 hours` |
| `<= 12 hours` | `6 - 12 hours` |
| `<= 24 hours` | `12 - 24 hours` |
| `<= 2 days` | `1 - 2 days` |
| `<= 3 days` | `2 - 3 days` |
| `<= 4 days` | `3 - 4 days` |
| `<= 5 days` | `4 - 5 days` |
| `<= 7 days` | `5 - 7 days` |
| `<= 10 days` | `7 - 10 days` |
| `<= 14 days` | `10 - 14 days` |
| `<= 21 days` | `2 - 3 weeks` |
| `<= 30 days` | `3 - 4 weeks` |
| `<= 45 days` | `1 - 1.5 months` |
| `<= 60 days` | `1.5 - 2 months` |
| `> 60 days` | `2+ months` |

## Are variants scored separately?

Yes – variants are scored independently from their base item. Supported Doppler, Gamma Doppler, and Case Hardened variants are returned under the base item in `variants`. Variant maps are keyed by display name, such as `Phase 1`, `Ruby`, or `Tier 1`. In a variant object, `market_hash_name` is the base item name, `name` is the full variant name, and `version` is the stable code.

## Request

`GET https://api.cs2.sh/v1/liquidity/items`

**curl**

```bash
curl https://api.cs2.sh/v1/liquidity/items \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  -H "Accept-Encoding: gzip" --compressed
```

**Python**

```python
import requests

headers = {
    "Authorization": "Bearer <<YOUR_API_KEY>>",
    "Accept-Encoding": "gzip",
}

response = requests.get(
    "https://api.cs2.sh/v1/liquidity/items",
    headers=headers,
)

response.raise_for_status()
data = response.json()
```

**Node**

```javascript
const headers = {
  "Authorization": "Bearer <<YOUR_API_KEY>>",
  "Accept-Encoding": "gzip",
};

const response = await fetch("https://api.cs2.sh/v1/liquidity/items", { headers });

if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
```

**Go**

```go
package main

import (
    "io"
    "net/http"
)

func main() {
    req, _ := http.NewRequest("GET", "https://api.cs2.sh/v1/liquidity/items", nil)
    req.Header.Set("Authorization", "Bearer <<YOUR_API_KEY>>")
    req.Header.Set("Accept-Encoding", "gzip")

    resp, err := http.DefaultClient.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    _, _ = io.ReadAll(resp.Body)
}
```

## Response

```json
{
  "response_time": "2026-07-26T00:00:29.508Z",
  "run_date": "2026-07-26",
  "items": {
    "USP-S | Printstream (Factory New)": {
      "market_hash_name": "USP-S | Printstream (Factory New)",
      "liquidity": "extremely_liquid",
      "estimated_sale_time": "1 - 2 hours"
    }
  }
}
```

## Response Object

### ItemLiquidityGetResponse

All-items liquidity snapshot. Returned by `GET /v1/liquidity/items`.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the snapshot was computed. |
| `run_date` | `string (date)` | UTC date for the daily computation. |
| `items` | `object` | Map of `market_hash_name` to item liquidity data. |

## Response fields

Each item maps to `liquidity` (bucket) and `estimated_sale_time` (range), with per-variant entries under `variants`. Full schema: [ItemLiquidityItem](/docs/api-reference/objects#itemliquidityitem).

### ItemLiquidityItem

Item liquidity bucket and estimated sale time for a single item.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Steam market hash name. |
| `liquidity` | `string` | Allowed: `unknown`, `extremely_illiquid`, `very_illiquid`, `illiquid`, `moderate`, `liquid`, `very_liquid`, `extremely_liquid`. Recomputed item liquidity bucket. |
| `estimated_sale_time` | `string` | Allowed: `under 1 hour`, `1 - 2 hours`, `2 - 6 hours`, `6 - 12 hours`, `12 - 24 hours`, `1 - 2 days`, `2 - 3 days`, `3 - 4 days`, `4 - 5 days`, `5 - 7 days`, `7 - 10 days`, `10 - 14 days`, `2 - 3 weeks`, `3 - 4 weeks`, `1 - 1.5 months`, `1.5 - 2 months`, `2+ months`, `unknown`. 80th-percentile estimated time for a competitively priced listing to sell. |
| `variants` | `object` | Per-variant item liquidity keyed by display name. |

- `market_hash_name`, `liquidity`, and `estimated_sale_time` are present on returned items.
- `variants` appears only for items with variant liquidity data.

## Errors

This endpoint returns the full snapshot.

| Status | When |
| --- | --- |
| `401` / `403` | Missing key, invalid key, or plan access. |
| `429` | Rate-limited. |
| `503` / `5xx` | Snapshot unavailable or server-side issue. |

---

# POST /v1/archive/history

Long-term archive prices, total supply, and sale volume from 2023 onward.

Returns comprehensive archive price data from BUFF, Youpin, and C5Game from 2023 onwards. Use this endpoint for long-term price history.

The `aggregate` source additionally includes both `hourly_volume` - the approximate number of sales within that hour - and `total_supply` - the approximate cumulative supply of that item. Archive history updates once or twice per day. Max 100 items per request.

## Access

Requires a Scale or Enterprise API key.

## Supported intervals

| Interval | Bucket |
| --- | --- |
| `1h` | Hourly archive buckets |
| `1d` | Daily archive buckets |

## Supported sources

| Source | Fields |
| --- | --- |
| `aggregate` | `ask`, `bid`, `ask_volume`, `bid_volume`, `hourly_volume`, `total_supply` |
| `buff` | `ask`, `bid`, `ask_volume`, `bid_volume` |
| `youpin` | `ask`, `bid`, `ask_volume`, `bid_volume` |
| `c5game` | `ask`, `bid`, `ask_volume`, `bid_volume` |

Default source selection: `aggregate`.

## Request

`POST https://api.cs2.sh/v1/archive/history`

**curl**

```bash
curl -X POST https://api.cs2.sh/v1/archive/history \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  -H "Accept-Encoding: gzip" --compressed \
  -H "Content-Type: application/json" \
  -d '{
  "items": [
    "USP-S | Printstream (Factory New)"
  ],
  "start": "2024-01-01",
  "end": "2026-07-26",
  "sources": [
    "aggregate",
    "buff"
  ],
  "interval": "1d"
}'
```

**Python**

```python
import requests

headers = {
    "Authorization": "Bearer <<YOUR_API_KEY>>",
    "Accept-Encoding": "gzip",
    "Content-Type": "application/json",
}

payload = {
    "items": ["USP-S | Printstream (Factory New)"],
    "start": "2024-01-01",
    "end": "2026-07-26",
    "sources": ["aggregate", "buff"],
    "interval": "1d",
}

response = requests.post(
    "https://api.cs2.sh/v1/archive/history",
    headers=headers,
    json=payload,
)

response.raise_for_status()
data = response.json()
```

**Node**

```javascript
const headers = {
  "Authorization": "Bearer <<YOUR_API_KEY>>",
  "Accept-Encoding": "gzip",
  "Content-Type": "application/json",
};

const response = await fetch("https://api.cs2.sh/v1/archive/history", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "items": [
      "USP-S | Printstream (Factory New)"
    ],
    "start": "2024-01-01",
    "end": "2026-07-26",
    "sources": [
      "aggregate",
      "buff"
    ],
    "interval": "1d"
  }),
});

if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
```

**Go**

```go
package main

import (
    "bytes"
    "encoding/json"
    "io"
    "net/http"
)

func main() {
    payload := map[string]any{
        "items": []any{
            "USP-S | Printstream (Factory New)",
        },
        "start": "2024-01-01",
        "end": "2026-07-26",
        "sources": []any{
            "aggregate",
            "buff",
        },
        "interval": "1d",
    }
    body, _ := json.Marshal(payload)
    req, _ := http.NewRequest("POST", "https://api.cs2.sh/v1/archive/history", bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Authorization", "Bearer <<YOUR_API_KEY>>")
    req.Header.Set("Accept-Encoding", "gzip")

    resp, err := http.DefaultClient.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    _, _ = io.ReadAll(resp.Body)
}
```

## Parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `items` | `string[]` | Yes | List of market_hash_name values (max 100) |
| `start` | `string` | Yes | Start date (YYYY-MM-DD or RFC3339) |
| `end` | `string` | No | End date (YYYY-MM-DD or RFC3339). Default now. |
| `sources` | `string[]` | No | Filter to specific sources. Default: aggregate only. |
| `interval` | `string` | No | Default: `1d`. Allowed: `1h`, `1d`. Aggregation interval |

## Response

```json
{
  "response_time": "2026-07-26T18:54:19.138233339Z",
  "currency": "USD",
  "start": "2026-04-27T00:00:00Z",
  "end": "2026-07-25T00:00:00Z",
  "interval": "1d",
  "items": {
    "USP-S | Printstream (Factory New)": {
      "market_hash_name": "USP-S | Printstream (Factory New)",
      "count": 89,
      "data": [
        {
          "bucket": "2026-04-27T00:00:00Z",
          "aggregate": {
            "time": "2026-04-27T23:59:07Z",
            "ask": 130.05,
            "ask_volume": 1225,
            "bid": 130.19,
            "bid_volume": 133,
            "hourly_volume": 27,
            "total_supply": 31291,
            "sample_count": 24
          },
          "buff": {
            "time": "2026-04-27T23:53:24Z",
            "ask": 133.12,
            "ask_volume": 405,
            "bid": 130.19,
            "bid_volume": 45,
            "sample_count": 24
          },
          "youpin": {
            "time": "2026-04-27T23:59:07Z",
            "ask": 130.05,
            "ask_volume": 510,
            "bid": 128.59,
            "bid_volume": 63,
            "sample_count": 24
          },
          "c5game": {
            "time": "2026-04-27T23:57:07Z",
            "ask": 132.21,
            "ask_volume": 139,
            "bid": 213.58,
            "bid_volume": 24,
            "sample_count": 24
          }
        }
      ]
    }
  }
}
```

## Response Object

### ArchiveHistoryResponse

Response shape for `POST /v1/archive/history`.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated. |
| `currency` | `string` | Currency code (always `USD`). |
| `start` | `string (date-time)` | Effective start of the queried range, floored to the interval boundary. |
| `end` | `string (date-time)` | Effective end of the queried range, ceiled to the interval boundary. Exclusive. |
| `interval` | `string` | Allowed: `1h`, `1d`. Archive bucket size. |
| `items` | `object` | Map of `market_hash_name` to archive time-series. |
| `errors` | `ItemError[]` | Per-item failures alongside successful results (partial success). |

## Response fields

Each item holds `count` and a `data[]` array of buckets. Each bucket has a `bucket` boundary plus per-platform objects (`aggregate`, `buff`, `youpin`, `c5game`) carrying last-observed `ask`/`bid`, `ask_volume`/`bid_volume`, `time`, and `sample_count`. `hourly_volume` and `total_supply` populate only on the `aggregate` platform.

- `bucket` is present on every archive bucket.
- Per-platform objects appear only when that platform has data in the bucket.
- Valid requested items with no archive data return `not_in_archive`.

Full schemas: [ArchiveHistoryItem](/docs/api-reference/objects#archivehistoryitem), [ArchiveHistoryBucket](/docs/api-reference/objects#archivehistorybucket), [ArchiveHistoryPlatformData](/docs/api-reference/objects#archivehistoryplatformdata).

### ArchiveHistoryItem

Long-term archive time-series for a single item.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Steam market hash name. |
| `count` | `integer` | Number of buckets with data. |
| `data` | `ArchiveHistoryBucket[]` | Archive buckets in chronological order. |
| `variants` | `object` | Per-variant archive time-series for items with Doppler / Gamma Doppler phases or Case Hardened tiers. Keyed by display name. |

### ArchiveHistoryBucket

A single archive time bucket. Each platform key is present only when data exists for that platform in this bucket.

| Field | Type | Description |
| --- | --- | --- |
| `bucket` | `string (date-time)` | Start of the time bucket (UTC-aligned to the interval boundary). |
| `aggregate` | `ArchiveHistoryPlatformData` | Per-platform price data within an archive bucket. `hourly_volume` and `total_supply` are populated only on the `aggregate` platform. |
| `buff` | `ArchiveHistoryPlatformData` | Per-platform price data within an archive bucket. `hourly_volume` and `total_supply` are populated only on the `aggregate` platform. |
| `youpin` | `ArchiveHistoryPlatformData` | Per-platform price data within an archive bucket. `hourly_volume` and `total_supply` are populated only on the `aggregate` platform. |
| `c5game` | `ArchiveHistoryPlatformData` | Per-platform price data within an archive bucket. `hourly_volume` and `total_supply` are populated only on the `aggregate` platform. |

### ArchiveHistoryPlatformData

Per-platform price data within an archive bucket. `hourly_volume` and `total_supply` are populated only on the `aggregate` platform.

| Field | Type | Description |
| --- | --- | --- |
| `time` | `string (date-time)` | Actual timestamp of the last observation in the bucket. Distinct from the bucket boundary. |
| `ask` | `number` | Last observed ask price (USD) in the bucket. |
| `ask_volume` | `integer` | Last observed number of items listed for sale. |
| `bid` | `number` | Last observed bid price (USD) in the bucket. |
| `bid_volume` | `integer` | Last observed number of buy orders. |
| `hourly_volume` | `number` | Aggregated trading volume metric (`aggregate` platform only). |
| `total_supply` | `number` | Total market supply metric (`aggregate` platform only). |
| `sample_count` | `integer` | Number of observations aggregated into this bucket. |

## Errors

| Status | When |
| --- | --- |
| `400 validation_error` | The request body or query failed validation (e.g. bad JSON, missing `items`/`start`, over 100 items, or a bad `interval` or date range). |
| `404 not_found` | No requested valid item has archive data. |
| `401` / `403` | Missing key, invalid key, or plan access. |
| `429` | Rate-limited. |
| `5xx` | Server-side issue. |

When some items resolve and others don't, the request still returns `200` with the resolved items plus an `errors[]` array – each entry is an [ItemError](/docs/api-reference/objects#itemerror) with a `code` of `unknown_item`, `invalid_format`, or `not_in_archive`.

---

# POST /v1/archive/csfloat

Daily sale price and volume from CSFloat from 2022 onward.

Returns time-series average sale price and volume from CSFloat. Data begins in 2022.

Data is daily and updated once or twice per day. Max 100 items per request.

## Access

Requires a Scale or Enterprise API key.

## Supported sources

| Source | Fields |
| --- | --- |
| `csfloat` | `price` (daily average sale price), `volume` (daily sales count) |

## Request

`POST https://api.cs2.sh/v1/archive/csfloat`

**curl**

```bash
curl -X POST https://api.cs2.sh/v1/archive/csfloat \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  -H "Accept-Encoding: gzip" --compressed \
  -H "Content-Type: application/json" \
  -d '{
  "items": [
    "USP-S | Printstream (Factory New)"
  ],
  "start": "2024-01-01",
  "end": "2026-07-26"
}'
```

**Python**

```python
import requests

headers = {
    "Authorization": "Bearer <<YOUR_API_KEY>>",
    "Accept-Encoding": "gzip",
    "Content-Type": "application/json",
}

payload = {
    "items": ["USP-S | Printstream (Factory New)"],
    "start": "2024-01-01",
    "end": "2026-07-26",
}

response = requests.post(
    "https://api.cs2.sh/v1/archive/csfloat",
    headers=headers,
    json=payload,
)

response.raise_for_status()
data = response.json()
```

**Node**

```javascript
const headers = {
  "Authorization": "Bearer <<YOUR_API_KEY>>",
  "Accept-Encoding": "gzip",
  "Content-Type": "application/json",
};

const response = await fetch("https://api.cs2.sh/v1/archive/csfloat", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "items": [
      "USP-S | Printstream (Factory New)"
    ],
    "start": "2024-01-01",
    "end": "2026-07-26"
  }),
});

if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
```

**Go**

```go
package main

import (
    "bytes"
    "encoding/json"
    "io"
    "net/http"
)

func main() {
    payload := map[string]any{
        "items": []any{
            "USP-S | Printstream (Factory New)",
        },
        "start": "2024-01-01",
        "end": "2026-07-26",
    }
    body, _ := json.Marshal(payload)
    req, _ := http.NewRequest("POST", "https://api.cs2.sh/v1/archive/csfloat", bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Authorization", "Bearer <<YOUR_API_KEY>>")
    req.Header.Set("Accept-Encoding", "gzip")

    resp, err := http.DefaultClient.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    _, _ = io.ReadAll(resp.Body)
}
```

## Parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `items` | `string[]` | Yes | List of market_hash_name values (max 100) |
| `start` | `string` | No | Start date (YYYY-MM-DD or RFC3339). Default 2020-01-01. |
| `end` | `string` | No | End date (YYYY-MM-DD or RFC3339). Default now. |

## Response

```json
{
  "response_time": "2026-07-26T18:54:19.632716841Z",
  "currency": "USD",
  "start": "2026-04-27T00:00:00Z",
  "end": "2026-07-25T00:00:00Z",
  "items": {
    "USP-S | Printstream (Factory New)": {
      "market_hash_name": "USP-S | Printstream (Factory New)",
      "count": 89,
      "data": [
        {
          "date": "2026-04-27",
          "price": 149.76,
          "volume": 8
        },
        {
          "date": "2026-04-28",
          "price": 189.81,
          "volume": 10
        }
      ]
    }
  }
}
```

## Response Object

### ArchiveCSFloatResponse

Response shape for `POST /v1/archive/csfloat`.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated. |
| `currency` | `string` | Currency code (always `USD`). |
| `start` | `string (date-time)` | Effective start of the queried range, floored to the day boundary. |
| `end` | `string (date-time)` | Effective end of the queried range, ceiled to the day boundary. Exclusive. |
| `items` | `object` | Map of `market_hash_name` to CSFloat sale time-series. |
| `errors` | `ItemError[]` | Per-item failures alongside successful results (partial success). |

## Response fields

Each item holds `count` and a `data[]` array of daily aggregates; variants nest under `variants`. Each aggregate carries `date` (`YYYY-MM-DD`, UTC), `price` (arithmetic average of all sale prices that day, USD), and `volume` (number of sales that day).

- `date`, `price`, and `volume` are present on returned daily aggregates.
- Variants appear under `variants` when CSFloat archive data exists for that variant.
- Valid requested items with no CSFloat archive data return `not_in_archive`.

Full schemas: [ArchiveCSFloatItem](/docs/api-reference/objects#archivecsfloatitem), [ArchiveCSFloatBucket](/docs/api-reference/objects#archivecsfloatbucket).

### ArchiveCSFloatItem

CSFloat sale time-series for a single item.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Steam market hash name. |
| `count` | `integer` | Number of days with data |
| `data` | `ArchiveCSFloatBucket[]` | Daily sale aggregates in chronological order. |
| `variants` | `object` | Per-variant CSFloat sale time-series for items with Doppler / Gamma Doppler phases or Case Hardened tiers. Keyed by display name. |

### ArchiveCSFloatBucket

One day of sale data on CSFloat.

| Field | Type | Description |
| --- | --- | --- |
| `date` | `string` | Date in `YYYY-MM-DD` format (UTC). |
| `price` | `number` | Arithmetic average of all sale prices (USD) that day. |
| `volume` | `integer` | Number of sales that day. |

## Errors

| Status | When |
| --- | --- |
| `400 validation_error` | The request body or query failed validation (e.g. bad JSON, missing `items`/`start`, over 100 items, or a bad `interval` or date range). |
| `404 not_found` | No requested valid item has CSFloat archive data. |
| `401` / `403` | Missing key, invalid key, or plan access. |
| `429` | Rate-limited. |
| `5xx` | Server-side issue. |

When some items resolve and others don't, the request still returns `200` with the resolved items plus an `errors[]` array – each entry is an [ItemError](/docs/api-reference/objects#itemerror) with a `code` of `unknown_item`, `invalid_format`, or `not_in_archive`.

---

# POST /v1/archive/steam

Native Steam Community Market median sale price and volume history - 13 years of data, daily since April 26, 2013.

Returns Steam Community Market median sale price and volume history.
- Daily (`1d`) buckets from April 26, 2013
- Hourly (`1h`) buckets from May 9, 2026

This is the same data that Steam exposes through their price graphs on any community market item page. Max 100 items per request.

## Access

Requires a Scale or Enterprise API key.

## Supported intervals

| Interval | Max range |
| --- | --- |
| `1h` | Unlimited |
| `1d` | Unlimited |

## Supported sources

| Source | Fields |
| --- | --- |
| `steam` | `price` (median sale price), `volume` (number of purchases) |

## Request

`POST https://api.cs2.sh/v1/archive/steam`

**curl**

```bash
curl -X POST https://api.cs2.sh/v1/archive/steam \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  -H "Accept-Encoding: gzip" --compressed \
  -H "Content-Type: application/json" \
  -d '{
  "items": [
    "USP-S | Printstream (Factory New)"
  ],
  "start": "2025-01-01",
  "end": "2025-02-01",
  "interval": "1d"
}'
```

**Python**

```python
import requests

headers = {
    "Authorization": "Bearer <<YOUR_API_KEY>>",
    "Accept-Encoding": "gzip",
    "Content-Type": "application/json",
}

payload = {
    "items": ["USP-S | Printstream (Factory New)"],
    "start": "2025-01-01",
    "end": "2025-02-01",
    "interval": "1d",
}

response = requests.post(
    "https://api.cs2.sh/v1/archive/steam",
    headers=headers,
    json=payload,
)

response.raise_for_status()
data = response.json()
```

**Node**

```javascript
const headers = {
  "Authorization": "Bearer <<YOUR_API_KEY>>",
  "Accept-Encoding": "gzip",
  "Content-Type": "application/json",
};

const response = await fetch("https://api.cs2.sh/v1/archive/steam", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "items": [
      "USP-S | Printstream (Factory New)"
    ],
    "start": "2025-01-01",
    "end": "2025-02-01",
    "interval": "1d"
  }),
});

if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
```

**Go**

```go
package main

import (
    "bytes"
    "encoding/json"
    "io"
    "net/http"
)

func main() {
    payload := map[string]any{
        "items": []any{
            "USP-S | Printstream (Factory New)",
        },
        "start": "2025-01-01",
        "end": "2025-02-01",
        "interval": "1d",
    }
    body, _ := json.Marshal(payload)
    req, _ := http.NewRequest("POST", "https://api.cs2.sh/v1/archive/steam", bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Authorization", "Bearer <<YOUR_API_KEY>>")
    req.Header.Set("Accept-Encoding", "gzip")

    resp, err := http.DefaultClient.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    _, _ = io.ReadAll(resp.Body)
}
```

## Parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `items` | `string[]` | Yes | List of regular `market_hash_name` values (max 100). Variants are not supported. |
| `start` | `string` | Yes | Start date/time as YYYY-MM-DD or RFC3339, inclusive. |
| `end` | `string` | No | End date/time as YYYY-MM-DD or RFC3339, exclusive. Defaults to now. |
| `interval` | `string` | Yes | Allowed: `1h`, `1d`. Native Steam bucket interval. No public max date range. |

## Response

```json
{
  "response_time": "2026-07-26T18:54:20.110090345Z",
  "currency": "USD",
  "start": "2025-01-01T00:00:00Z",
  "end": "2025-02-01T00:00:00Z",
  "interval": "1d",
  "items": {
    "USP-S | Printstream (Factory New)": {
      "market_hash_name": "USP-S | Printstream (Factory New)",
      "count": 31,
      "data": [
        {
          "bucket": "2025-01-01T00:00:00Z",
          "price": 150.23,
          "volume": 7
        }
      ]
    }
  }
}
```

## Response Object

### ArchiveSteamResponse

Response shape for `POST /v1/archive/steam`. Valid regular items with no rows return item-level `not_in_archive`; if every valid regular item has no rows, the endpoint returns `404 not_found`.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | Required. When the response was generated. |
| `currency` | `string` | Required. Currency code (always `USD`). |
| `start` | `string (date-time)` | Required. Normalized UTC inclusive start. |
| `end` | `string (date-time)` | Required. Normalized UTC exclusive end. |
| `interval` | `string` | Required. Allowed: `1h`, `1d`. Requested native Steam interval for every returned bucket. |
| `items` | `object` | Required. Map of `market_hash_name` to native Steam sale-history buckets. |
| `errors` | `ItemError[]` | Per-item failures alongside successful results (partial success). |

## Response fields

Each item holds `count` and a `data[]` array of buckets. Each bucket carries its `bucket` boundary, `price` (Steam's median sale price), and `volume` (number of purchases).

- `bucket` is present on every bucket.
- Variant items are not supported.
- Valid requested items with no Steam history return `not_in_archive`; if every valid item has none, the endpoint returns `404 not_found`.

Full schemas: [ArchiveSteamItem](/docs/api-reference/objects#archivesteamitem), [ArchiveSteamBucket](/docs/api-reference/objects#archivesteambucket).

### ArchiveSteamItem

Native Steam sale-history buckets for one regular item. No variants are returned.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Required. Canonical regular Steam market hash name. |
| `count` | `integer` | Required. Number of buckets in `data`. |
| `data` | `ArchiveSteamBucket[]` | Required. Buckets sorted ascending by `bucket`. |

### ArchiveSteamBucket

One native Steam sale-history bucket. `price` is Steam median sale price and `volume` is purchases.

| Field | Type | Description |
| --- | --- | --- |
| `bucket` | `string (date-time)` | Required. Native Steam bucket start. |
| `price` | `number` | Required. Steam median sale price in USD. |
| `volume` | `integer` | Required. Steam purchase count. |

## Errors

| Status | When |
| --- | --- |
| `400 validation_error` | The request body or query failed validation (e.g. bad JSON, missing `items`/`start`, over 100 items, or a bad `interval` or date range). |
| `401` / `403` | Missing key, invalid key, or plan access. |
| `404 not_found` | Every valid regular item has no Steam archive rows. |
| `429` | Rate-limited. |
| `5xx` | Server-side issue. |

When some items resolve and others do not, the request still returns `200` with the resolved items plus an `errors[]` array. Variant requests use `unsupported_variant`.

---

# POST /v1/archive/youpin

Youpin sale history API for CS2 - sale prices at 1h/4h/12h intervals in USD, 12h data since November 12, 2025, updated 1-2 times per day.

Returns Youpin sale history at three frequencies.
- `12h` frequency from November 12, 2025
- `4h` frequency from June 27, 2026
- `1h` frequency from July 20, 2026

Youpin publishes *one sale* per sampling bucket and doesn't provide any sale volume. This means that, for the 1 hour interval, the maximum sample count will be 24 per day, and 6 / 2 for the 4 and 12-hour respectively. This is the same data as Youpin's native sale-graphs. To estimate a minimum sale volume, you can count non-overlapping sale price & time occurrences within a given period by combining several intervals.

Approximately ~16,000 items are currently supported (anything >= liquid), with all Doppler & Gamma Doppler items. Data updates 1-2 times per day. Max 100 items per request.

## Access

Requires a Scale or Enterprise API key.

## Supported intervals

| Interval | Sampling bucket |
| --- | --- |
| `1h` | One sale per hour |
| `4h` | One sale per 4 hours |
| `12h` | One sale per 12 hours |

All observed intervals return together under each item's `intervals` map, each as an independent series.

## Supported sources

| Source | Fields |
| --- | --- |
| `youpin` | `price` (sale price, USD) |

## Request

`POST https://api.cs2.sh/v1/archive/youpin`

**curl**

```bash
curl -X POST https://api.cs2.sh/v1/archive/youpin \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  -H "Accept-Encoding: gzip" --compressed \
  -H "Content-Type: application/json" \
  -d '{
  "items": [
    "★ Karambit | Doppler (Factory New)"
  ],
  "start": "2026-01-29",
  "end": "2026-07-28"
}'
```

**Python**

```python
import requests

headers = {
    "Authorization": "Bearer <<YOUR_API_KEY>>",
    "Accept-Encoding": "gzip",
    "Content-Type": "application/json",
}

payload = {
    "items": ["★ Karambit | Doppler (Factory New)"],
    "start": "2026-01-29",
    "end": "2026-07-28",
}

response = requests.post(
    "https://api.cs2.sh/v1/archive/youpin",
    headers=headers,
    json=payload,
)

response.raise_for_status()
data = response.json()
```

**Node**

```javascript
const headers = {
  "Authorization": "Bearer <<YOUR_API_KEY>>",
  "Accept-Encoding": "gzip",
  "Content-Type": "application/json",
};

const response = await fetch("https://api.cs2.sh/v1/archive/youpin", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "items": [
      "★ Karambit | Doppler (Factory New)"
    ],
    "start": "2026-01-29",
    "end": "2026-07-28"
  }),
});

if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
```

**Go**

```go
package main

import (
    "bytes"
    "encoding/json"
    "io"
    "net/http"
)

func main() {
    payload := map[string]any{
        "items": []any{
            "★ Karambit | Doppler (Factory New)",
        },
        "start": "2026-01-29",
        "end": "2026-07-28",
    }
    body, _ := json.Marshal(payload)
    req, _ := http.NewRequest("POST", "https://api.cs2.sh/v1/archive/youpin", bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Authorization", "Bearer <<YOUR_API_KEY>>")
    req.Header.Set("Accept-Encoding", "gzip")

    resp, err := http.DefaultClient.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    _, _ = io.ReadAll(resp.Body)
}
```

## Parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `items` | `string[]` | Yes | List of market_hash_name values (max 100) |
| `start` | `string` | No | Start date (YYYY-MM-DD or RFC3339). Default 180 days ago. Floored to the hour. |
| `end` | `string` | No | End date (YYYY-MM-DD or RFC3339). Default now. Ceiled to the hour. |

## Response

```json
{
  "response_time": "2026-07-28T16:20:41.318204951Z",
  "currency": "USD",
  "start": "2026-01-29T00:00:00Z",
  "end": "2026-07-28T00:00:00Z",
  "items": {
    "★ Karambit | Doppler (Factory New)": {
      "market_hash_name": "★ Karambit | Doppler (Factory New)",
      "intervals": {
        "1h": {
          "count": 120,
          "data": [
            {
              "bucket": "2026-07-21T16:00:00Z",
              "time": "2026-07-21T16:52:38.307Z",
              "price": 1314.88
            },
            {
              "bucket": "2026-07-21T23:00:00Z",
              "time": "2026-07-21T23:42:05.008Z",
              "price": 1920.6
            }
          ]
        },
        "4h": {
          "count": 180,
          "data": [
            {
              "bucket": "2026-06-27T16:00:00Z",
              "time": "2026-06-27T18:37:02.696Z",
              "price": 1971.09
            },
            {
              "bucket": "2026-06-27T20:00:00Z",
              "time": "2026-06-27T23:59:41.06Z",
              "price": 1995.59
            }
          ]
        },
        "12h": {
          "count": 353,
          "data": [
            {
              "bucket": "2026-01-29T16:00:00Z",
              "time": "2026-01-30T03:34:33.138Z",
              "price": 2256.76
            },
            {
              "bucket": "2026-01-30T16:00:00Z",
              "time": "2026-01-31T03:51:57.426Z",
              "price": 1438.64
            }
          ]
        }
      },
      "variants": {
        "Phase 2": {
          "market_hash_name": "★ Karambit | Doppler (Factory New)",
          "name": "★ Karambit | Doppler (Factory New) | Phase 2",
          "display_name": "Phase 2",
          "version": "p2",
          "intervals": {
            "12h": {
              "count": 356,
              "data": [
                {
                  "bucket": "2026-01-29T04:00:00Z",
                  "time": "2026-01-29T15:46:01.526Z",
                  "price": 2296.22
                }
              ]
            }
          }
        }
      }
    }
  }
}
```

## Response Object

### ArchiveYoupinResponse

Response shape for `POST /v1/archive/youpin`.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated. |
| `currency` | `string` | Currency code (always `USD`). |
| `start` | `string (date-time)` | Effective start of the queried range, floored to the 1h boundary. |
| `end` | `string (date-time)` | Effective end of the queried range, ceiled to the 1h boundary. Exclusive. |
| `items` | `object` | Map of `market_hash_name` to Youpin sale series. |
| `errors` | `ItemError[]` | Per-item failures alongside successful results (partial success). |

## Response fields

Each item holds an `intervals` map keyed `1h`, `4h`, and `12h`, each an independent series of `count` and `data[]`; variants nest under `variants`. Each point carries `bucket` (the sampling boundary), `time` (the actual sale time), and `price` (USD, converted at the sale date's exchange rate).

- An interval key appears only when that width was observed in the window; `count: 0` means observed with no sales.
- Valid requested items with no Youpin sale history return `not_in_archive`.

Full schemas: [ArchiveYoupinItem](/docs/api-reference/objects#archiveyoupinitem), [ArchiveYoupinSeries](/docs/api-reference/objects#archiveyoupinseries), [ArchiveYoupinPoint](/docs/api-reference/objects#archiveyoupinpoint).

### ArchiveYoupinItem

Youpin sale history for a single item, served as one independent series per provider sampling interval.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Steam market hash name. |
| `intervals` | `object` | Independent series keyed by provider sampling interval, emitted in `1h`, `4h`, `12h` order. A key is present only when that interval was observed inside the requested window, so an entry that exists only to carry requested variants returns `{}`. |
| `variants` | `object` | Per-variant Youpin sale history for items with Doppler or Gamma Doppler phases or Case Hardened tiers. Keyed by display name, and omitted when empty. A variant series never falls back to base history. |

### ArchiveYoupinSeries

One independent Youpin sale series at a single provider sampling interval, carrying exactly `count` and `data`. Series are never stitched, summed, or interleaved with one another.

| Field | Type | Description |
| --- | --- | --- |
| `count` | `integer` | Number of points in this series, equal to the length of `data`. This is not a sale volume, and `count` of 0 with an empty `data` means the interval was observed and no sales landed in the window. |
| `data` | `ArchiveYoupinPoint[]` | Sales at this interval, ordered by bucket. |

### ArchiveYoupinPoint

One sale on Youpin. Youpin keeps one sale per sampling bucket, so a point is a real sale, not an aggregate. The sampling interval is the series key, never a field on the point.

| Field | Type | Description |
| --- | --- | --- |
| `bucket` | `string (date-time)` | Start of the provider sampling bucket the point represents, at the width of the series holding it. |
| `time` | `string (date-time)` | Actual sale time inside the bucket. |
| `price` | `number` | Sale price (USD), converted from CNY at the sale date's own historical rate, or `null` when no rate for that date could be resolved. |

## Errors

| Status | When |
| --- | --- |
| `400 validation_error` | The request body or query failed validation (e.g. bad JSON, missing `items`, over 100 items, or `start` not before `end`). |
| `404 not_found` | No requested valid item has Youpin sale history in the window. |
| `401` / `403` | Missing key, invalid key, or plan access. |
| `429` | Rate-limited. |
| `5xx` | Server-side issue. |

When some items resolve and others don't, the request still returns `200` with the resolved items plus an `errors[]` array - each entry is an [ItemError](/docs/api-reference/objects#itemerror) with a `code` of `unknown_item`, `invalid_format`, `not_in_archive`, `unsupported_source` (the item has no Youpin identity), or `unsupported_variant` (the variant has no Youpin sale-history selector).

---

# GET /v1/market/buff/latest

BUFF float ranges and fade ranges for every item.

Returns current BUFF bid/ask prices for every item, split into float ranges, fade ranges, and variant ranges.

This endpoint's prices update every 10 minutes.

## Access

Available on all plans (Developer, Scale, Enterprise).

## What range types does BUFF expose?

Each item is split into `base`, `float`, `fade`, and `float_fade` buckets.

| `bucket_type` | Meaning |
| --- | --- |
| `base` | Aggregated across the entire item or variant. |
| `float` | Float range. `float.min` and `float.max` describe the range. |
| `fade` | Fade percentage range. `fade.min` and `fade.max` describe the range. |
| `float_fade` | Combined float range and fade range. |

Items with Doppler phases or Case Hardened tiers can include `variants`; see [Response Format](/docs/response-format#variants). Each variant has its own ranges in `buckets[]`.

## How do float and fade ranges work?

Range boundaries are inclusive on `min`, exclusive on `max`. `bucket_id` is stable across latest and history.

Float ranges vary by item, exterior, and float cap.

You can find typical float range sets below:

| Exterior | Common BUFF float ranges |
| --- | --- |
| Factory New | `0:0.01`, `0.01:0.02`, `0.02:0.03`, `0.03:0.04`, `0.04:0.07` |
| Minimal Wear | `0.07:0.08`, `0.08:0.09`, `0.09:0.10`, `0.10:0.11`, `0.11:0.15` |
| Field-Tested | `0.15:0.18`, `0.18:0.21`, `0.21:0.24`, `0.24:0.27`, `0.27:0.38` |
| Well-Worn | `0.38:0.39`, `0.39:0.40`, `0.40:0.41`, `0.41:0.42`, `0.42:0.45` |
| Battle-Scarred | Commonly `0.45:0.50`, `0.50:0.63`, `0.63:0.76`, `0.76:0.90`, `0.90:1` |

Fade ranges use fade percentage, not float. Fade items may have `fade` ranges and combined `float_fade` ranges.

## Prices and volumes

| Field | Meaning |
| --- | --- |
| `ask` | Lowest listing price in the range, USD. |
| `avg_ask` | Average listing price in the range, USD. |
| `bid` | Highest buy order in the range, USD. |
| `ask_volume` | Listings currently in the range. |
| `bid_volume` | Active buy orders for the range. |

## Supported sources

| Source | Fields |
| --- | --- |
| `buff` | `ask`, `avg_ask`, `bid`, `ask_volume`, `bid_volume` |

## Request

`GET https://api.cs2.sh/v1/market/buff/latest`

**curl**

```bash
curl https://api.cs2.sh/v1/market/buff/latest \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  -H "Accept-Encoding: gzip" --compressed
```

**Python**

```python
import requests

headers = {
    "Authorization": "Bearer <<YOUR_API_KEY>>",
    "Accept-Encoding": "gzip",
}

response = requests.get(
    "https://api.cs2.sh/v1/market/buff/latest",
    headers=headers,
)

response.raise_for_status()
data = response.json()
```

**Node**

```javascript
const headers = {
  "Authorization": "Bearer <<YOUR_API_KEY>>",
  "Accept-Encoding": "gzip",
};

const response = await fetch("https://api.cs2.sh/v1/market/buff/latest", { headers });

if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
```

**Go**

```go
package main

import (
    "io"
    "net/http"
)

func main() {
    req, _ := http.NewRequest("GET", "https://api.cs2.sh/v1/market/buff/latest", nil)
    req.Header.Set("Authorization", "Bearer <<YOUR_API_KEY>>")
    req.Header.Set("Accept-Encoding", "gzip")

    resp, err := http.DefaultClient.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    _, _ = io.ReadAll(resp.Body)
}
```

## Response

```json
{
  "response_time": "2026-07-26T18:54:14.833093145Z",
  "currency": "USD",
  "items": {
    "AK-47 | Case Hardened (Field-Tested)": {
      "market_hash_name": "AK-47 | Case Hardened (Field-Tested)",
      "buckets": [
        {
          "bucket_id": "base",
          "bucket_type": "base",
          "updated_at": "2026-07-26T18:46:12Z",
          "collected_at": "2026-07-26T18:50:54.164Z",
          "ask": 213.23,
          "avg_ask": 216.98,
          "bid": 203.78,
          "ask_volume": 982,
          "bid_volume": 31
        },
        {
          "bucket_id": "float:0.15:0.18",
          "bucket_type": "float",
          "float": {
            "min": 0.15,
            "max": 0.18
          },
          "updated_at": "2026-07-26T18:46:12Z",
          "collected_at": "2026-07-26T18:50:54.164Z",
          "ask": 218.55,
          "avg_ask": 231.47,
          "bid": 203.78,
          "ask_volume": 219,
          "bid_volume": 10
        }
      ],
      "variants": {
        "Tier 1": {
          "market_hash_name": "AK-47 | Case Hardened (Field-Tested)",
          "name": "AK-47 | Case Hardened (Field-Tested) | Tier 1",
          "display_name": "Tier 1",
          "version": "t1",
          "buckets": [
            {
              "bucket_id": "variant:t1",
              "bucket_type": "base",
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 1328.96,
              "avg_ask": 2218.76,
              "bid": 1077.98,
              "ask_volume": 78,
              "bid_volume": 13
            },
            {
              "bucket_id": "variant:t1|float:0.15:0.18",
              "bucket_type": "float",
              "float": {
                "min": 0.15,
                "max": 0.18
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 2584.21,
              "avg_ask": 12532.95,
              "bid": 1077.98,
              "ask_volume": 12,
              "bid_volume": 15
            },
            {
              "bucket_id": "variant:t1|float:0.18:0.21",
              "bucket_type": "float",
              "float": {
                "min": 0.18,
                "max": 0.21
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 1609.44,
              "avg_ask": 14470.85,
              "bid": 1079.46,
              "ask_volume": 11,
              "bid_volume": 23
            },
            {
              "bucket_id": "variant:t1|float:0.21:0.24",
              "bucket_type": "float",
              "float": {
                "min": 0.21,
                "max": 0.24
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 2215.04,
              "avg_ask": 33480.73,
              "bid": 1079.46,
              "ask_volume": 9,
              "bid_volume": 23
            },
            {
              "bucket_id": "variant:t1|float:0.24:0.27",
              "bucket_type": "float",
              "float": {
                "min": 0.24,
                "max": 0.27
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 2953.23,
              "avg_ask": 19841.46,
              "bid": 1079.46,
              "ask_volume": 7,
              "bid_volume": 23
            },
            {
              "bucket_id": "variant:t1|float:0.27:0.38",
              "bucket_type": "float",
              "float": {
                "min": 0.27,
                "max": 0.38
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 1328.96,
              "avg_ask": 3056.22,
              "bid": 1079.46,
              "ask_volume": 39,
              "bid_volume": 16
            }
          ]
        },
        "Tier 2": {
          "market_hash_name": "AK-47 | Case Hardened (Field-Tested)",
          "name": "AK-47 | Case Hardened (Field-Tested) | Tier 2",
          "display_name": "Tier 2",
          "version": "t2",
          "buckets": [
            {
              "bucket_id": "variant:t2",
              "bucket_type": "base",
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 389.77,
              "avg_ask": 398.86,
              "bid": 366.22,
              "ask_volume": 235,
              "bid_volume": 14
            },
            {
              "bucket_id": "variant:t2|float:0.15:0.18",
              "bucket_type": "float",
              "float": {
                "min": 0.15,
                "max": 0.18
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 443.01,
              "avg_ask": 521.14,
              "bid": 366.22,
              "ask_volume": 49,
              "bid_volume": 16
            },
            {
              "bucket_id": "variant:t2|float:0.18:0.21",
              "bucket_type": "float",
              "float": {
                "min": 0.18,
                "max": 0.21
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 407.57,
              "avg_ask": 515.91,
              "bid": 366.22,
              "ask_volume": 38,
              "bid_volume": 17
            },
            {
              "bucket_id": "variant:t2|float:0.21:0.24",
              "bucket_type": "float",
              "float": {
                "min": 0.21,
                "max": 0.24
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 394.28,
              "avg_ask": 672.67,
              "bid": 366.22,
              "ask_volume": 18,
              "bid_volume": 16
            },
            {
              "bucket_id": "variant:t2|float:0.24:0.27",
              "bucket_type": "float",
              "float": {
                "min": 0.24,
                "max": 0.27
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 389.77,
              "avg_ask": 449.59,
              "bid": 366.22,
              "ask_volume": 32,
              "bid_volume": 15
            },
            {
              "bucket_id": "variant:t2|float:0.27:0.38",
              "bucket_type": "float",
              "float": {
                "min": 0.27,
                "max": 0.38
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 389.85,
              "avg_ask": 408.05,
              "bid": 366.22,
              "ask_volume": 98,
              "bid_volume": 15
            }
          ]
        },
        "Tier 3": {
          "market_hash_name": "AK-47 | Case Hardened (Field-Tested)",
          "name": "AK-47 | Case Hardened (Field-Tested) | Tier 3",
          "display_name": "Tier 3",
          "version": "t3",
          "buckets": [
            {
              "bucket_id": "variant:t3",
              "bucket_type": "base",
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 216.26,
              "avg_ask": 235.87,
              "bid": 203.78,
              "ask_volume": 295,
              "bid_volume": 10
            },
            {
              "bucket_id": "variant:t3|float:0.15:0.18",
              "bucket_type": "float",
              "float": {
                "min": 0.15,
                "max": 0.18
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 221.36,
              "avg_ask": 252.9,
              "bid": 203.78,
              "ask_volume": 65,
              "bid_volume": 10
            },
            {
              "bucket_id": "variant:t3|float:0.18:0.21",
              "bucket_type": "float",
              "float": {
                "min": 0.18,
                "max": 0.21
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 236.12,
              "avg_ask": 300.55,
              "bid": 203.78,
              "ask_volume": 41,
              "bid_volume": 10
            },
            {
              "bucket_id": "variant:t3|float:0.21:0.24",
              "bucket_type": "float",
              "float": {
                "min": 0.21,
                "max": 0.24
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 233.02,
              "avg_ask": 276.7,
              "bid": 203.78,
              "ask_volume": 41,
              "bid_volume": 10
            },
            {
              "bucket_id": "variant:t3|float:0.24:0.27",
              "bucket_type": "float",
              "float": {
                "min": 0.24,
                "max": 0.27
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 248.08,
              "avg_ask": 288.19,
              "bid": 203.78,
              "ask_volume": 38,
              "bid_volume": 10
            },
            {
              "bucket_id": "variant:t3|float:0.27:0.38",
              "bucket_type": "float",
              "float": {
                "min": 0.27,
                "max": 0.38
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 216.26,
              "avg_ask": 246.05,
              "bid": 203.78,
              "ask_volume": 110,
              "bid_volume": 10
            }
          ]
        },
        "Tier 4": {
          "market_hash_name": "AK-47 | Case Hardened (Field-Tested)",
          "name": "AK-47 | Case Hardened (Field-Tested) | Tier 4",
          "display_name": "Tier 4",
          "version": "t4",
          "buckets": [
            {
              "bucket_id": "variant:t4",
              "bucket_type": "base",
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 213.23,
              "avg_ask": 217.52,
              "bid": 203.78,
              "ask_volume": 362,
              "bid_volume": 10
            },
            {
              "bucket_id": "variant:t4|float:0.15:0.18",
              "bucket_type": "float",
              "float": {
                "min": 0.15,
                "max": 0.18
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 218.55,
              "avg_ask": 233.7,
              "bid": 203.78,
              "ask_volume": 91,
              "bid_volume": 10
            },
            {
              "bucket_id": "variant:t4|float:0.18:0.21",
              "bucket_type": "float",
              "float": {
                "min": 0.18,
                "max": 0.21
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 221.5,
              "avg_ask": 234.11,
              "bid": 203.78,
              "ask_volume": 59,
              "bid_volume": 10
            },
            {
              "bucket_id": "variant:t4|float:0.21:0.24",
              "bucket_type": "float",
              "float": {
                "min": 0.21,
                "max": 0.24
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 213.23,
              "avg_ask": 240.46,
              "bid": 203.78,
              "ask_volume": 41,
              "bid_volume": 10
            },
            {
              "bucket_id": "variant:t4|float:0.24:0.27",
              "bucket_type": "float",
              "float": {
                "min": 0.24,
                "max": 0.27
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 216.52,
              "avg_ask": 267.28,
              "bid": 203.78,
              "ask_volume": 33,
              "bid_volume": 10
            },
            {
              "bucket_id": "variant:t4|float:0.27:0.38",
              "bucket_type": "float",
              "float": {
                "min": 0.27,
                "max": 0.38
              },
              "updated_at": "2026-07-26T18:46:12Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 213.38,
              "avg_ask": 220.17,
              "bid": 203.78,
              "ask_volume": 138,
              "bid_volume": 10
            }
          ]
        }
      }
    },
    "★ M9 Bayonet | Doppler (Factory New)": {
      "market_hash_name": "★ M9 Bayonet | Doppler (Factory New)",
      "variants": {
        "Phase 2": {
          "market_hash_name": "★ M9 Bayonet | Doppler (Factory New)",
          "name": "★ M9 Bayonet | Doppler (Factory New) | Phase 2",
          "display_name": "Phase 2",
          "version": "p2",
          "buckets": [
            {
              "bucket_id": "variant:p2",
              "bucket_type": "base",
              "updated_at": "2026-07-26T18:46:27Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 1321.49,
              "avg_ask": 1327.42,
              "bid": 1281.77,
              "ask_volume": 261,
              "bid_volume": 22
            },
            {
              "bucket_id": "variant:p2|float:0.00:0.01",
              "bucket_type": "float",
              "float": {
                "min": 0,
                "max": 0.01
              },
              "updated_at": "2026-07-26T18:46:27Z",
              "collected_at": "2026-07-26T18:50:54.164Z",
              "ask": 1336.26,
              "avg_ask": 1365.19,
              "bid": 1284.72,
              "ask_volume": 60,
              "bid_volume": 25
            }
          ]
        }
      }
    }
  }
}
```

## Response Object

### BUFFMarketFloatLatestResponse

All-items BUFF market float/fade snapshot. Returned by `GET /v1/market/buff/latest`. Prices are converted USD only; raw CNY fields and BUFF internal lineage are not exposed.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated. |
| `currency` | `string` | Currency code (always `USD`). |
| `items` | `object` | Map of `market_hash_name` to per-item BUFF data. |

## Response fields

Each item holds ranges in `buckets[]`; variants nest under `variants`. Each entry carries range identity (`bucket_id`, `bucket_type`, `float`/`fade`), price and volume fields, and `updated_at`/`collected_at`.

| Field | Appears on |
| --- | --- |
| `bucket_id`, `bucket_type`, `updated_at`, `collected_at` | All returned ranges |
| `float` | `float` and `float_fade` ranges |
| `fade` | `fade` and `float_fade` ranges |

Full schemas: [BUFFMarketFloatItem](/docs/api-reference/objects#buffmarketfloatitem), [BUFFMarketFloatLatestBucket](/docs/api-reference/objects#buffmarketfloatlatestbucket), [BUFFMarketFloatRange](/docs/api-reference/objects#buffmarketfloatrange), [BUFFMarketFloatVariant](/docs/api-reference/objects#buffmarketfloatvariant).

### BUFFMarketFloatItem

BUFF market float/fade data for one item.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Canonical base `market_hash_name`. |
| `buckets` | `BUFFMarketFloatLatestBucket[]` | Latest BUFF buckets for the base listing. |
| `variants` | `object` | Per-variant BUFF data for items with Doppler / Gamma Doppler phases or Case Hardened tiers. Keyed by display name (e.g. `Phase 1`, `Ruby`, `Tier 1`). |

### BUFFMarketFloatLatestBucket

One latest BUFF market bucket. Buckets are stratified by `bucket_type` (`base`, `float`, `fade`, `float_fade`); raw CNY prices and BUFF internal lineage are not exposed.

| Field | Type | Description |
| --- | --- | --- |
| `bucket_id` | `string` | Stable bucket identifier (e.g. `base`, `float:0.15:0.18`, `variant:p2\|float:0.00:0.01`). |
| `bucket_type` | `string` | Allowed: `base`, `float`, `fade`, `float_fade`. Bucket stratification. - `base`: aggregated across the entire item or variant. - `float`: float-range slice (see `float`). - `fade`: fade-percentage slice (see `fade`). - `float_fade`: combined float and fade slice. |
| `float` | `BUFFMarketFloatRange` | Numeric range for a `float` or `fade` bucket. `min` is inclusive, `max` is exclusive. |
| `fade` | `BUFFMarketFloatRange` | Numeric range for a `float` or `fade` bucket. `min` is inclusive, `max` is exclusive. |
| `updated_at` | `string (date-time)` | When BUFF last refreshed this bucket. |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this bucket. |
| `ask` | `number` | Lowest ask price (USD) in this bucket. |
| `avg_ask` | `number` | Average ask price (USD) in the bucket. |
| `bid` | `number` | Highest buy-order price (USD) on BUFF. |
| `ask_volume` | `integer` | Number of items listed for sale in this bucket. |
| `bid_volume` | `integer` | Number of active buy orders against this bucket. |

### BUFFMarketFloatRange

Numeric range for a `float` or `fade` bucket. `min` is inclusive, `max` is exclusive.

| Field | Type | Description |
| --- | --- | --- |
| `min` | `number` | Inclusive lower bound. |
| `max` | `number` | Exclusive upper bound. |

### BUFFMarketFloatVariant

BUFF latest data for a single variant of an item (Doppler / Gamma Doppler phase or Case Hardened tier).

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Base item's `market_hash_name`. Full variant name lives in `name`. |
| `name` | `string` | The variant's full `market_hash_name`, e.g. `★ M9 Bayonet \| Doppler (Factory New) \| Phase 1`. |
| `display_name` | `string` | Human-readable variant label (e.g. `Phase 1`, `Ruby`, `Tier 1`). |
| `version` | `string` | Stable variant code. Switch on this in client code. |
| `buckets` | `BUFFMarketFloatLatestBucket[]` | Latest BUFF buckets for this variant. |

## Errors

This endpoint returns the full snapshot.

| Status | When |
| --- | --- |
| `401` / `403` | Missing key, invalid key, or plan access. |
| `429` | Rate-limited. |
| `503` / `5xx` | Snapshot unavailable or server-side issue. |

---

# POST /v1/market/buff/history

OHLC history for BUFF float ranges and fade ranges since May 19, 2026.

Returns OHLC history for BUFF float ranges and fade ranges. Data begins on May 19, 2026.

Each range from [GET /v1/market/buff/latest](/docs/api-reference/market-buff-latest) has its own time series, including per-variant ranges for Doppler phases and Case Hardened tiers. OHLC is computed for `ask`, `avg_ask`, and `bid`; `ask_volume` and `bid_volume` are last-observed. Since data for this endpoint is also surfaced in `v1/market/buff/latest`, prices update every 10 minutes. Max 100 items per request.

## Access

Requires a Scale or Enterprise API key.

## Supported intervals

| Interval | Max range |
| --- | --- |
| `30m` | 90 days |
| `1h` | 365 days |
| `1d` | Unlimited |

## Supported sources

| Source | Fields |
| --- | --- |
| `buff` | `ask`, `avg_ask`, `bid` (OHLC); `ask_volume`, `bid_volume` (last-observed) |

`bucket` is the UTC interval boundary. `open_time` and `close_time` are the first and last observation timestamps inside the bucket.

## Request

`POST https://api.cs2.sh/v1/market/buff/history`

**curl**

```bash
curl -X POST https://api.cs2.sh/v1/market/buff/history \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  -H "Accept-Encoding: gzip" --compressed \
  -H "Content-Type: application/json" \
  -d '{
  "items": [
    "★ Bayonet | Fade (Factory New)",
    "AK-47 | Case Hardened (Field-Tested)"
  ],
  "start": "2026-07-20",
  "end": "2026-07-23",
  "interval": "1h"
}'
```

**Python**

```python
import requests

headers = {
    "Authorization": "Bearer <<YOUR_API_KEY>>",
    "Accept-Encoding": "gzip",
    "Content-Type": "application/json",
}

payload = {
    "items": ["★ Bayonet | Fade (Factory New)", "AK-47 | Case Hardened (Field-Tested)"],
    "start": "2026-07-20",
    "end": "2026-07-23",
    "interval": "1h",
}

response = requests.post(
    "https://api.cs2.sh/v1/market/buff/history",
    headers=headers,
    json=payload,
)

response.raise_for_status()
data = response.json()
```

**Node**

```javascript
const headers = {
  "Authorization": "Bearer <<YOUR_API_KEY>>",
  "Accept-Encoding": "gzip",
  "Content-Type": "application/json",
};

const response = await fetch("https://api.cs2.sh/v1/market/buff/history", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "items": [
      "★ Bayonet | Fade (Factory New)",
      "AK-47 | Case Hardened (Field-Tested)"
    ],
    "start": "2026-07-20",
    "end": "2026-07-23",
    "interval": "1h"
  }),
});

if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
```

**Go**

```go
package main

import (
    "bytes"
    "encoding/json"
    "io"
    "net/http"
)

func main() {
    payload := map[string]any{
        "items": []any{
            "★ Bayonet | Fade (Factory New)",
            "AK-47 | Case Hardened (Field-Tested)",
        },
        "start": "2026-07-20",
        "end": "2026-07-23",
        "interval": "1h",
    }
    body, _ := json.Marshal(payload)
    req, _ := http.NewRequest("POST", "https://api.cs2.sh/v1/market/buff/history", bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Authorization", "Bearer <<YOUR_API_KEY>>")
    req.Header.Set("Accept-Encoding", "gzip")

    resp, err := http.DefaultClient.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    _, _ = io.ReadAll(resp.Body)
}
```

## Parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `items` | `string[]` | Yes | List of market_hash_name values (max 100) |
| `start` | `string` | Yes | Start date/time as YYYY-MM-DD or RFC3339 |
| `end` | `string` | No | End date/time as YYYY-MM-DD or RFC3339. Defaults to now. |
| `interval` | `string` | No | Default: `30m`. Allowed: `30m`, `1h`, `1d`. |

## Response

```json
{
  "response_time": "2026-07-26T18:54:21.429446677Z",
  "currency": "USD",
  "start": "2026-07-20T00:00:00Z",
  "end": "2026-07-23T00:00:00Z",
  "interval": "1h",
  "items": {
    "★ Bayonet | Fade (Factory New)": {
      "market_hash_name": "★ Bayonet | Fade (Factory New)",
      "buckets": [
        {
          "bucket_id": "base",
          "bucket_type": "base",
          "data": [
            {
              "bucket": "2026-07-20T00:00:00Z",
              "updated_at": "2026-07-20T00:46:24Z",
              "collected_at": "2026-07-20T00:50:57.483Z",
              "open_ask": 371.36,
              "high_ask": 371.57,
              "low_ask": 371.36,
              "close_ask": 371.57,
              "open_avg_ask": 379.74,
              "high_avg_ask": 379.96,
              "low_avg_ask": 379.74,
              "close_avg_ask": 379.96,
              "open_bid": 359.57,
              "high_bid": 359.78,
              "low_bid": 359.57,
              "close_bid": 359.78,
              "ask_volume": 177,
              "bid_volume": 23,
              "open_time": "2026-07-20T00:00:53.231Z",
              "close_time": "2026-07-20T00:50:57.483Z"
            }
          ]
        }
      ]
    }
  }
}
```

## Response Object

### BUFFMarketFloatHistoryResponse

Response shape for `POST /v1/market/buff/history`. Returns OHLC history for each requested BUFF market float/fade bucket.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated. |
| `currency` | `string` | Currency code (always `USD`). |
| `start` | `string (date-time)` | Effective start of the queried range, floored to the interval boundary. |
| `end` | `string (date-time)` | Effective end of the queried range, ceiled to the interval boundary. Exclusive. |
| `interval` | `string` | Allowed: `30m`, `1h`, `1d`. OHLC bucket size. |
| `items` | `object` | Map of `market_hash_name` to per-item BUFF history. |
| `errors` | `ItemError[]` | Per-item failures alongside successful results (partial success). |

## Response fields

Each item holds ranges in `buckets[]`; each entry carries range identity (`bucket_id`, `bucket_type`, `float`/`fade`, matching `GET /v1/market/buff/latest`) and a `data[]` array of OHLC points. Each point carries OHLC of `ask`, `avg_ask`, and `bid`, last-observed `ask_volume`/`bid_volume`, and the real observation window (`open_time`/`close_time`).

| Field | Appears on |
| --- | --- |
| `bucket_id`, `bucket_type`, `data` | All returned ranges |
| `float` | `float` and `float_fade` ranges |
| `fade` | `fade` and `float_fade` ranges |
| `bucket`, `updated_at`, `collected_at`, `open_time`, `close_time` | All history points |

Full schemas: [BUFFMarketFloatHistoryItem](/docs/api-reference/objects#buffmarketfloathistoryitem), [BUFFMarketFloatHistoryBucket](/docs/api-reference/objects#buffmarketfloathistorybucket), [BUFFMarketFloatHistoryPoint](/docs/api-reference/objects#buffmarketfloathistorypoint).

### BUFFMarketFloatHistoryItem

BUFF market float/fade OHLC history for one item.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Canonical base `market_hash_name`. |
| `buckets` | `BUFFMarketFloatHistoryBucket[]` | OHLC history for the base listing's buckets. |
| `variants` | `object` | Per-variant OHLC history for items with Doppler / Gamma Doppler phases or Case Hardened tiers. Keyed by display name. |

### BUFFMarketFloatHistoryBucket

OHLC history for one BUFF market bucket. Each entry in `data` is one interval, in chronological order.

| Field | Type | Description |
| --- | --- | --- |
| `bucket_id` | `string` | Stable bucket identifier (e.g. `fade:99:100`, `variant:p2\|float:0.00:0.01`). |
| `bucket_type` | `string` | Allowed: `base`, `float`, `fade`, `float_fade`. Bucket stratification – see `BUFFMarketFloatLatestBucket.bucket_type`. |
| `float` | `BUFFMarketFloatRange` | Numeric range for a `float` or `fade` bucket. `min` is inclusive, `max` is exclusive. |
| `fade` | `BUFFMarketFloatRange` | Numeric range for a `float` or `fade` bucket. `min` is inclusive, `max` is exclusive. |
| `data` | `BUFFMarketFloatHistoryPoint[]` | OHLC observations for this bucket, chronological. |

### BUFFMarketFloatHistoryPoint

A single OHLC observation inside a BUFF market float/fade bucket history.

| Field | Type | Description |
| --- | --- | --- |
| `bucket` | `string (date-time)` | UTC-aligned start of the OHLC interval. |
| `updated_at` | `string (date-time)` | When BUFF last refreshed the bucket inside this interval. |
| `collected_at` | `string (date-time)` | When cs2.sh fetched the source rows inside this interval. |
| `open_ask` | `number` | First ask price (USD) observed in the interval. |
| `high_ask` | `number` | Highest ask price (USD) observed in the interval. |
| `low_ask` | `number` | Lowest ask price (USD) observed in the interval. |
| `close_ask` | `number` | Last ask price (USD) observed in the interval. |
| `open_avg_ask` | `number` | First `avg_ask` value observed in the interval. |
| `high_avg_ask` | `number` | Highest `avg_ask` value observed in the interval. |
| `low_avg_ask` | `number` | Lowest `avg_ask` value observed in the interval. |
| `close_avg_ask` | `number` | Last `avg_ask` value observed in the interval. |
| `open_bid` | `number` | First bid price (USD) observed in the interval. |
| `high_bid` | `number` | Highest bid price (USD) observed in the interval. |
| `low_bid` | `number` | Lowest bid price (USD) observed in the interval. |
| `close_bid` | `number` | Last bid price (USD) observed in the interval. |
| `ask_volume` | `integer` | Last observed ask volume inside the interval. |
| `bid_volume` | `integer` | Last observed bid volume inside the interval. |
| `open_time` | `string (date-time)` | Timestamp of the first observation inside the interval. Distinct from `bucket` (the interval boundary). |
| `close_time` | `string (date-time)` | Timestamp of the last observation inside the interval. Distinct from `bucket` (the interval boundary). |

## Errors

| Status | When |
| --- | --- |
| `400 validation_error` | The request body or query failed validation (e.g. bad JSON, missing `items`/`start`, over 100 items, or a bad `interval` or date range). |
| `401` / `403` | Missing key, invalid key, or plan access. |
| `429` | Rate-limited. |
| `5xx` | Server-side issue. |

When some items resolve and others don't, the request still returns `200` with the resolved items plus an `errors[]` array – each entry is an [ItemError](/docs/api-reference/objects#itemerror) with a `code` of `unknown_item`, `invalid_format`, or `not_in_cache`.

---

# GET /v1/market/steam/latest

Full-depth Steam bid/ask orderbooks for every item.

Returns the latest full-depth snapshot of the Steam bid/ask orderbook for all items.

This snapshot includes every tracked regular item, so the response is large (~100mb). Like all other requests, `Accept-Encoding: gzip` is required. Full ladders are returned as columnar `depth.asks.prices`/`depth.asks.volumes` and `depth.bids.prices`/`depth.bids.volumes` arrays. Ask prices are sorted ascending, bid prices are sorted descending, and `volumes` is the quantity at each price level.

This endpoint's prices update every 10 minutes for liquid items and every 60 minutes for other items - liquidity is determined by `liquidity/items`.

## Access

Available on all plans (Developer, Scale, Enterprise).

## Supported sources

| Source | Fields |
| --- | --- |
| `steam` | `top` (best ask/bid and total order counts), `depth` (full columnar bid/ask ladders) |

## Request

`GET https://api.cs2.sh/v1/market/steam/latest`

**curl**

```bash
curl https://api.cs2.sh/v1/market/steam/latest \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  -H "Accept-Encoding: gzip" --compressed
```

**Python**

```python
import requests

headers = {
    "Authorization": "Bearer <<YOUR_API_KEY>>",
    "Accept-Encoding": "gzip",
}

response = requests.get(
    "https://api.cs2.sh/v1/market/steam/latest",
    headers=headers,
)

response.raise_for_status()
data = response.json()
```

**Node**

```javascript
const headers = {
  "Authorization": "Bearer <<YOUR_API_KEY>>",
  "Accept-Encoding": "gzip",
};

const response = await fetch("https://api.cs2.sh/v1/market/steam/latest", { headers });

if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
```

**Go**

```go
package main

import (
    "io"
    "net/http"
)

func main() {
    req, _ := http.NewRequest("GET", "https://api.cs2.sh/v1/market/steam/latest", nil)
    req.Header.Set("Authorization", "Bearer <<YOUR_API_KEY>>")
    req.Header.Set("Accept-Encoding", "gzip")

    resp, err := http.DefaultClient.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    _, _ = io.ReadAll(resp.Body)
}
```

## Response

```json
{
  "response_time": "2026-07-26T18:54:14.123567967Z",
  "currency": "USD",
  "as_of": "2026-07-26T18:53:53.202Z",
  "items": {
    "USP-S | Printstream (Factory New)": {
      "updated_at": "2026-07-26T18:52:21.42Z",
      "collected_at": "2026-07-26T18:52:56.46Z",
      "top": {
        "ask": 169.14,
        "ask_volume": 70,
        "bid": 155.05,
        "bid_volume": 2951
      },
      "depth": {
        "ask_levels": 2,
        "bid_levels": 2,
        "asks": {
          "prices": [
            169.14,
            169.4
          ],
          "volumes": [
            1,
            1
          ]
        },
        "bids": {
          "prices": [
            155.05,
            154.88
          ],
          "volumes": [
            1,
            1
          ]
        }
      }
    }
  }
}
```

## Response Object

### SteamOrderbookLatestResponse

All-items latest Steam orderbook snapshot. Returned by `GET /v1/market/steam/latest` from a pre-gzipped cache. No variants or internal lineage fields are exposed.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | Required. Cache serialization/build time. |
| `currency` | `string` | Required. Currency code (always `USD`). |
| `as_of` | `string (date-time)` | Required. Maximum selected `updated_at` across rows included in this cache snapshot. |
| `items` | `object` | Required. Fresh regular items keyed by `market_hash_name`. |

## Response fields

Each item carries `updated_at`, `collected_at`, `top`, and `depth`. `top` contains best ask/bid prices and total Steam ask/bid order counts. `depth` contains full columnar ask and bid ladders. Variants items are not included.

Full schemas: [SteamOrderbookItem](/docs/api-reference/objects#steamorderbookitem), [SteamOrderbookTop](/docs/api-reference/objects#steamorderbooktop), [SteamOrderbookDepth](/docs/api-reference/objects#steamorderbookdepth), [SteamOrderbookDepthSide](/docs/api-reference/objects#steamorderbookdepthside).

### SteamOrderbookItem

Latest full-depth Steam orderbook for one regular item. No cent fields, item IDs, currency IDs, variants, or raw lineage fields are exposed.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | Required. Steam observation time selected for this orderbook. |
| `collected_at` | `string (date-time)` | Required. When cs2.sh collected or ingested the selected row. |
| `top` | `SteamOrderbookTop` | Required. Top-of-book best ask/bid for a Steam orderbook. Each field is `null` when that side is absent. |
| `depth` | `SteamOrderbookDepth` | Required. Full-depth Steam orderbook ladders in columnar form. |

### SteamOrderbookTop

Top-of-book best ask/bid for a Steam orderbook. Each field is `null` when that side is absent.

| Field | Type | Description |
| --- | --- | --- |
| `ask` | `number` | Required. Best sell price in USD, or `null` when absent. |
| `ask_volume` | `integer` | Required. Total Steam sell-order count, or `null` when absent. |
| `bid` | `number` | Required. Best buy-order price in USD, or `null` when absent. |
| `bid_volume` | `integer` | Required. Total Steam buy-order count, or `null` when absent. |

### SteamOrderbookDepth

Full-depth Steam orderbook ladders in columnar form.

| Field | Type | Description |
| --- | --- | --- |
| `ask_levels` | `integer` | Required. Number of ask levels in `asks`. |
| `bid_levels` | `integer` | Required. Number of bid levels in `bids`. |
| `asks` | `SteamOrderbookDepthSide` | Required. One side of the orderbook ladder in columnar form. `prices[i]` pairs with `volumes[i]`; each `volume` is the quantity available at that exact price, not cumulative. |
| `bids` | `SteamOrderbookDepthSide` | Required. One side of the orderbook ladder in columnar form. `prices[i]` pairs with `volumes[i]`; each `volume` is the quantity available at that exact price, not cumulative. |

### SteamOrderbookDepthSide

One side of the orderbook ladder in columnar form. `prices[i]` pairs with `volumes[i]`; each `volume` is the quantity available at that exact price, not cumulative.

| Field | Type | Description |
| --- | --- | --- |
| `prices` | `number[]` | Required. Decimal USD prices. Asks ascending, bids descending. |
| `volumes` | `integer[]` | Required. Quantity available at each corresponding price. |

## Errors

| Status | When |
| --- | --- |
| `401` / `403` | Missing key, invalid key, or plan access. |
| `429` | Rate-limited. |
| `503 service_unavailable` | Latest orderbook cache is missing, stale, or empty. |
| `5xx` | Server-side issue. |

---

# POST /v1/market/steam/history

Full-depth Steam orderbook snapshots over time.

Returns full-depth Steam orderbook snapshots over time, the same shape as [GET /v1/market/steam/latest](/docs/api-reference/market-steam-latest). Data begins on June 9, 2026. Max 100 items per request.

Data for this endpoint updates every 10 minutes.

## Access

Requires a Scale or Enterprise API key.

## Supported intervals

| Interval | Max range |
| --- | --- |
| `1h` | 90 days |
| `1d` | Unlimited |

## Supported sources

| Source | Fields |
| --- | --- |
| `steam` | `top` (best ask/bid and total order counts), `depth` (full columnar bid/ask ladders) |

## Request

`POST https://api.cs2.sh/v1/market/steam/history`

**curl**

```bash
curl -X POST https://api.cs2.sh/v1/market/steam/history \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  -H "Accept-Encoding: gzip" --compressed \
  -H "Content-Type: application/json" \
  -d '{
  "items": [
    "USP-S | Printstream (Factory New)"
  ],
  "start": "2026-07-20",
  "end": "2026-07-23",
  "interval": "1h"
}'
```

**Python**

```python
import requests

headers = {
    "Authorization": "Bearer <<YOUR_API_KEY>>",
    "Accept-Encoding": "gzip",
    "Content-Type": "application/json",
}

payload = {
    "items": ["USP-S | Printstream (Factory New)"],
    "start": "2026-07-20",
    "end": "2026-07-23",
    "interval": "1h",
}

response = requests.post(
    "https://api.cs2.sh/v1/market/steam/history",
    headers=headers,
    json=payload,
)

response.raise_for_status()
data = response.json()
```

**Node**

```javascript
const headers = {
  "Authorization": "Bearer <<YOUR_API_KEY>>",
  "Accept-Encoding": "gzip",
  "Content-Type": "application/json",
};

const response = await fetch("https://api.cs2.sh/v1/market/steam/history", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "items": [
      "USP-S | Printstream (Factory New)"
    ],
    "start": "2026-07-20",
    "end": "2026-07-23",
    "interval": "1h"
  }),
});

if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
```

**Go**

```go
package main

import (
    "bytes"
    "encoding/json"
    "io"
    "net/http"
)

func main() {
    payload := map[string]any{
        "items": []any{
            "USP-S | Printstream (Factory New)",
        },
        "start": "2026-07-20",
        "end": "2026-07-23",
        "interval": "1h",
    }
    body, _ := json.Marshal(payload)
    req, _ := http.NewRequest("POST", "https://api.cs2.sh/v1/market/steam/history", bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Authorization", "Bearer <<YOUR_API_KEY>>")
    req.Header.Set("Accept-Encoding", "gzip")

    resp, err := http.DefaultClient.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    _, _ = io.ReadAll(resp.Body)
}
```

## Parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `items` | `string[]` | Yes | List of regular `market_hash_name` values (max 100). Variants are not supported. |
| `start` | `string` | Yes | Start date/time as YYYY-MM-DD or RFC3339, inclusive. |
| `end` | `string` | No | End date/time as YYYY-MM-DD or RFC3339, exclusive. Defaults to now. |
| `interval` | `string` | Yes | Allowed: `1h`, `1d`. Bucket interval. `1h` is limited to 90 days; `1d` is unlimited. |

## Response

```json
{
  "response_time": "2026-07-26T18:54:23.061441059Z",
  "currency": "USD",
  "start": "2026-07-20T00:00:00Z",
  "end": "2026-07-23T00:00:00Z",
  "interval": "1h",
  "items": {
    "USP-S | Printstream (Factory New)": {
      "count": 72,
      "data": [
        {
          "bucket": "2026-07-20T00:00:00Z",
          "updated_at": "2026-07-20T00:54:22.006Z",
          "collected_at": "2026-07-20T00:55:13.298Z",
          "top": {
            "ask": 161.62,
            "ask_volume": 69,
            "bid": 155.43,
            "bid_volume": 2940
          },
          "depth": {
            "ask_levels": 1,
            "bid_levels": 1,
            "asks": {
              "prices": [
                161.62
              ],
              "volumes": [
                1
              ]
            },
            "bids": {
              "prices": [
                155.43
              ],
              "volumes": [
                1
              ]
            }
          }
        }
      ]
    }
  }
}
```

## Response Object

### SteamOrderbookHistoryResponse

Response shape for `POST /v1/market/steam/history`. Valid regular items with no rows are omitted; if all valid regular items have no rows, `items` is empty.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | Required. When the response was generated. |
| `currency` | `string` | Required. Currency code (always `USD`). |
| `start` | `string (date-time)` | Required. Normalized UTC inclusive start. |
| `end` | `string (date-time)` | Required. Normalized UTC exclusive end. |
| `interval` | `string` | Required. Allowed: `1h`, `1d`. Requested bucket interval. |
| `items` | `object` | Required. Map of `market_hash_name` to returned orderbook history. |
| `errors` | `ItemError[]` | Per-item failures alongside successful results (partial success). |

## Response fields

Each item holds `count` (buckets with data) and a `data[]` array of orderbook snapshots. Each point is the latest full-depth observation inside its `bucket`, carrying `updated_at`, `collected_at`, `top`, and `depth`. `top` contains best ask/bid prices and total Steam ask/bid order counts. `depth` contains full columnar ask and bid ladders.

- `bucket` is the UTC interval boundary.
- Variants items are not included.
- Valid requested items with no buckets in the range are omitted from `items`.

Full schemas: [SteamOrderbookHistoryItem](/docs/api-reference/objects#steamorderbookhistoryitem), [SteamOrderbookHistoryPoint](/docs/api-reference/objects#steamorderbookhistorypoint), [SteamOrderbookTop](/docs/api-reference/objects#steamorderbooktop), [SteamOrderbookDepth](/docs/api-reference/objects#steamorderbookdepth), [SteamOrderbookDepthSide](/docs/api-reference/objects#steamorderbookdepthside).

### SteamOrderbookHistoryItem

Steam orderbook bucket snapshots for one regular item. No variants are returned.

| Field | Type | Description |
| --- | --- | --- |
| `count` | `integer` | Required. Number of points in `data`. |
| `data` | `SteamOrderbookHistoryPoint[]` | Required. Points sorted ascending by `bucket`. |

### SteamOrderbookHistoryPoint

One latest-in-bucket full-depth Steam orderbook snapshot. This is not OHLC data.

| Field | Type | Description |
| --- | --- | --- |
| `bucket` | `string (date-time)` | Required. UTC bucket start. |
| `updated_at` | `string (date-time)` | Required. Latest Steam observation selected inside this bucket. |
| `collected_at` | `string (date-time)` | Required. When cs2.sh collected or ingested the selected row. |
| `top` | `SteamOrderbookTop` | Required. Top-of-book best ask/bid for a Steam orderbook. Each field is `null` when that side is absent. |
| `depth` | `SteamOrderbookDepth` | Required. Full-depth Steam orderbook ladders in columnar form. |

### SteamOrderbookTop

Top-of-book best ask/bid for a Steam orderbook. Each field is `null` when that side is absent.

| Field | Type | Description |
| --- | --- | --- |
| `ask` | `number` | Required. Best sell price in USD, or `null` when absent. |
| `ask_volume` | `integer` | Required. Total Steam sell-order count, or `null` when absent. |
| `bid` | `number` | Required. Best buy-order price in USD, or `null` when absent. |
| `bid_volume` | `integer` | Required. Total Steam buy-order count, or `null` when absent. |

### SteamOrderbookDepth

Full-depth Steam orderbook ladders in columnar form.

| Field | Type | Description |
| --- | --- | --- |
| `ask_levels` | `integer` | Required. Number of ask levels in `asks`. |
| `bid_levels` | `integer` | Required. Number of bid levels in `bids`. |
| `asks` | `SteamOrderbookDepthSide` | Required. One side of the orderbook ladder in columnar form. `prices[i]` pairs with `volumes[i]`; each `volume` is the quantity available at that exact price, not cumulative. |
| `bids` | `SteamOrderbookDepthSide` | Required. One side of the orderbook ladder in columnar form. `prices[i]` pairs with `volumes[i]`; each `volume` is the quantity available at that exact price, not cumulative. |

### SteamOrderbookDepthSide

One side of the orderbook ladder in columnar form. `prices[i]` pairs with `volumes[i]`; each `volume` is the quantity available at that exact price, not cumulative.

| Field | Type | Description |
| --- | --- | --- |
| `prices` | `number[]` | Required. Decimal USD prices. Asks ascending, bids descending. |
| `volumes` | `integer[]` | Required. Quantity available at each corresponding price. |

## Errors

| Status | When |
| --- | --- |
| `400 validation_error` | The request body or query failed validation (e.g. bad JSON, missing `items`/`start`, over 100 items, or a bad `interval` or date range). |
| `401` / `403` | Missing key, invalid key, or plan access. |
| `429` | Rate-limited. |
| `5xx` | Server-side issue. |

When some items resolve and others do not, the request still returns `200` with the resolved items plus an `errors[]` array.

---

# GET /v1/schema

Full CS2 item catalog keyed by market_hash_name – metadata, wears, variants, marketplace ids, and images.

Returns a single schema containing all Counter-Strike 2 items. It's updated automatically when the game updates and contains ~47,500 items and ~110 collections keyed by `market_hash_name`, with rarities, wears and float ranges, marketplace ids, and item images.

Variants are supported. All items map back to their corresponding collections / containers.

## Access

Available on all plans, including Demo and Developer.

## Request

`GET https://api.cs2.sh/v1/schema`

**curl**

```bash
curl https://api.cs2.sh/v1/schema \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  -H "Accept-Encoding: gzip" --compressed
```

**Python**

```python
import requests

headers = {
    "Authorization": "Bearer <<YOUR_API_KEY>>",
    "Accept-Encoding": "gzip",
}

response = requests.get(
    "https://api.cs2.sh/v1/schema",
    headers=headers,
)

response.raise_for_status()
data = response.json()
```

**Node**

```javascript
const headers = {
  "Authorization": "Bearer <<YOUR_API_KEY>>",
  "Accept-Encoding": "gzip",
};

const response = await fetch("https://api.cs2.sh/v1/schema", { headers });

if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
```

**Go**

```go
package main

import (
    "io"
    "net/http"
)

func main() {
    req, _ := http.NewRequest("GET", "https://api.cs2.sh/v1/schema", nil)
    req.Header.Set("Authorization", "Bearer <<YOUR_API_KEY>>")
    req.Header.Set("Accept-Encoding", "gzip")

    resp, err := http.DefaultClient.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    _, _ = io.ReadAll(resp.Body)
}
```

## Response

```json
{
  "schema_version": "v3",
  "generated_at": "2026-07-20T22:44:41Z",
  "counts": {
    "items": 47538,
    "by_category": {
      "agent": 63,
      "collectible": 468,
      "container": 479,
      "graffiti": 2111,
      "highlight_reel": 926,
      "key": 39,
      "keychain": 78,
      "music_kit": 188,
      "patch": 112,
      "skin": 21924,
      "sticker": 10553,
      "sticker_slab": 10553,
      "tool": 4,
      "vanilla_skin": 40
    },
    "collections": 110
  },
  "rarities": [
    {
      "key": "default",
      "name": "Stock",
      "tier": 0,
      "color": "#b0c3d9"
    },
    {
      "key": "common",
      "name": "Consumer Grade",
      "tier": 1,
      "color": "#b0c3d9"
    },
    {
      "key": "uncommon",
      "name": "Industrial Grade",
      "tier": 2,
      "color": "#5e98d9"
    },
    {
      "key": "rare",
      "name": "Mil-Spec Grade",
      "tier": 3,
      "color": "#4b69ff"
    },
    {
      "key": "mythical",
      "name": "Restricted",
      "tier": 4,
      "color": "#8847ff"
    },
    {
      "key": "legendary",
      "name": "Classified",
      "tier": 5,
      "color": "#d32ce6"
    },
    {
      "key": "ancient",
      "name": "Covert",
      "tier": 6,
      "color": "#eb4b4b"
    },
    {
      "key": "immortal",
      "name": "Contraband",
      "tier": 7,
      "color": "#e4ae39"
    }
  ],
  "collections": {
    "2025 Community Sticker Collection": {
      "name": "2025 Community Sticker Collection",
      "kind": "sticker",
      "release_date": "2025-10-01",
      "released_at": "2025-10-01T23:42:32Z",
      "update_name": "Community Maps, Charms, and More",
      "announcement_url": "https://steamcommunity.com/games/CSGO/announcements/detail/498333631688738073",
      "image": "https://cs2.sh/image/5-y5BqjoeymuHNzv",
      "steam_image": "https://cdn.steamstatic.com/apps/730/icons/econ/set_icons/set_community_2025.280d945244b90804541bf84784796793fd3bad00.png"
    },
    "Auto Racing Sticker Collection": {
      "name": "Auto Racing Sticker Collection",
      "kind": "sticker",
      "release_date": "2026-07-08",
      "released_at": "2026-07-08T22:50:43Z",
      "update_name": "Season 5, Armory, and More",
      "announcement_url": "https://steamcommunity.com/games/CSGO/announcements/detail/701021228894257509",
      "image": "https://cs2.sh/image/UuGTutGWjf5OvoVM",
      "steam_image": "https://cdn.steamstatic.com/apps/730/icons/econ/set_icons/set_auto_racing.2bb35a9a9c95a4757596a2ebd2085c73529f184b.png"
    },
    "...": "..."
  },
  "items": {
    "USP-S | Printstream (Factory New)": {
      "market_hash_name": "USP-S | Printstream (Factory New)",
      "category": "skin",
      "image": "https://cs2.sh/image/N8Agkakkrq4y1Hm1",
      "steam_image": "https://community.akamai.steamstatic.com/economy/image/i0CoZ81Ui0m-9KwlBY1L_18myuGuq1wfhWSaZgMttyVfPaERSR0Wqmu7LAocGIGz3UqlXOLrxM-vMGmW8VNxu5Dx60noTyLkjYbf7itX6vytbbZSI-WsG3SA_v5kue99XD2hkBwqjDGMnYftb3yUPFR0XsNyRrNc5kO5ltziMenr5lONj4kXyi2riywc7y9o5LtQAqQ7uvqAkScWnv4",
      "is_tradable": true,
      "rarity": {
        "name": "Covert",
        "tier": 6,
        "color": "#eb4b4b"
      },
      "collections": [
        "The Recoil Collection"
      ],
      "containers": [
        "Recoil Case"
      ],
      "ids": {
        "buff": 900565,
        "youpin": 102375,
        "c5game": 1017617021485346800
      },
      "def_index": 61,
      "base_name": "USP-S | Printstream",
      "weapon": "USP-S",
      "finish": "Printstream",
      "wears": [
        "Factory New",
        "Minimal Wear",
        "Field-Tested",
        "Well-Worn",
        "Battle-Scarred"
      ],
      "has_stattrak": true,
      "has_souvenir": true,
      "float_range": {
        "min": 0,
        "max": 0.85
      },
      "paint_index": 1142,
      "wear": "Factory New",
      "wear_float_range": {
        "min": 0,
        "max": 0.07
      },
      "stattrak": false,
      "souvenir": false
    },
    "★ Karambit | Doppler (Factory New)": {
      "market_hash_name": "★ Karambit | Doppler (Factory New)",
      "category": "skin",
      "image": "https://cs2.sh/image/vJQM7YiSwMZS1GsE",
      "steam_image": "https://community.akamai.steamstatic.com/economy/image/i0CoZ81Ui0m-9KwlBY1L_18myuGuq1wfhWSaZgMttyVfPaERSR0Wqmu7LAocGIGz3UqlXOLrxM-vMGmW8VNxu5Dx60noTyL6kJ_m-B1Q7uCvZaZkNM-SA1iSze91u_FsTju_qhAmoT-Jn4bjJC_4Ml93UtZuRLQPsBawkNfiMbnl5AKMiopCnin7iCJBv31j4rkBBKEg-6zUjV3GY6p9v8dpLWT3Fg",
      "is_tradable": true,
      "rarity": {
        "name": "Covert",
        "tier": 6,
        "color": "#eb4b4b"
      },
      "containers": [
        "Chroma Case",
        "Chroma 2 Case",
        "Chroma 3 Case"
      ],
      "ids": {
        "buff": 42998,
        "youpin": 1785,
        "c5game": 22702
      },
      "def_index": 507,
      "base_name": "★ Karambit | Doppler",
      "weapon": "Karambit",
      "finish": "Doppler",
      "wears": [
        "Factory New",
        "Minimal Wear"
      ],
      "has_stattrak": true,
      "has_souvenir": false,
      "float_range": {
        "min": 0,
        "max": 0.08
      },
      "wear": "Factory New",
      "wear_float_range": {
        "min": 0,
        "max": 0.07
      },
      "stattrak": false,
      "souvenir": false,
      "variants": [
        {
          "market_hash_name": "★ Karambit | Doppler (Factory New) | Phase 1",
          "family": "doppler",
          "name": "Phase 1",
          "image": "https://cs2.sh/image/f7tv2IWIqPDquMsV",
          "steam_image": "https://community.akamai.steamstatic.com/economy/image/i0CoZ81Ui0m-9KwlBY1L_18myuGuq1wfhWSaZgMttyVfPaERSR0Wqmu7LAocGIGz3UqlXOLrxM-vMGmW8VNxu5Dx60noTyL6kJ_m-B1Q7uCvZaZkNM-SA1iUzv5mvOR7cDm7lA4i4gKJk4jxNWXFb1cpDJR2FOFbsBTql9bjYbzq7gPZiN1MxH7_2ytNuCdpte1UB_Ui5OSJ2GbkVqni",
          "phase": "Phase 1",
          "color": "#6e1b3a",
          "paint_index": 418
        },
        "..."
      ]
    },
    "...": "..."
  },
  "generation_id": "7673916425787288234-20260726T052826Z"
}
```

## Response Object

### SchemaResponse

Response shape for `GET /v1/schema` – the full item catalog with metadata, keyed by `market_hash_name`.

| Field | Type | Description |
| --- | --- | --- |
| `schema_version` | `string` | Required. Catalog schema version. Re-sync clients when it changes. |
| `generation_id` | `string` | Required. Additive identifier for the immutable generation shared by the public API and site-data artifacts. |
| `generated_at` | `string (date-time)` | Required. When this immutable catalog generation was built. Use `generation_id` or the response ETag to detect a generation change. |
| `counts` | `object` | Required. Catalog entity counts. |
| `rarities` | `SchemaRarity[]` | Rarity tiers. |
| `collections` | `object` | Collection metadata keyed by collection name. |
| `items` | `object` | Required. Item records keyed by `market_hash_name`. |

## Response fields

`items` maps each `market_hash_name` (the same names the price endpoints accept). `collections` and `rarities` describe the collections and rarity tiers those records reference.

- Fields that do not apply to an item are omitted.
- `ids` holds the `buff`, `youpin`, and `c5game` catalog ids where known.
- `def_index` and `paint_index` are the game's item definition and paint kit indexes.
- Base items with variants list them under `variants`; variant rows link back through `variant`.
- `is_tradable` is `false` for items that cannot be traded.

Full schemas: [SchemaItem](/docs/api-reference/objects#schemaitem), [SchemaItemVariant](/docs/api-reference/objects#schemaitemvariant), [SchemaCollection](/docs/api-reference/objects#schemacollection), and [SchemaRarity](/docs/api-reference/objects#schemararity).

### SchemaItem

One catalog record, keyed by `market_hash_name` in the top-level `items` map. Fields that do not apply to the item are omitted.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Required. Canonical Steam market hash name (matches the price endpoints). |
| `category` | `string` | Required. Item category (e.g. `skin`, `sticker`, `container`, `agent`). |
| `image` | `string` | Required. Owned image URL served from `cs2.sh`. |
| `steam_image` | `string` | Optional official Valve Economy/static image URL, emitted only when the exact item origin is independently proven. Its absence does not remove the required owned `image`. |
| `is_tradable` | `boolean` | Required. Whether the item can be traded. |
| `rarity` | `object` | Item rarity – `name`, `tier`, and `color`. |
| `collections` | `string[]` | Collections the item belongs to. Omitted when none. |
| `containers` | `string[]` | Containers the item drops from. Omitted when none. |
| `ids` | `object` | Marketplace catalog ids where known. |
| `def_index` | `integer` | Item definition index. |
| `base_name` | `string` | Base item name without the wear suffix. Skins only. |
| `weapon` | `string` | Weapon name. Skins only. |
| `finish` | `string` | Finish name. Skins only. |
| `paint_index` | `integer` | Paint kit index. Skins only; omitted on Doppler and Gamma Doppler base items. |
| `wears` | `string[]` | Wears the item exists in. Wear-carrying items only. |
| `has_stattrak` | `boolean` | Whether a StatTrak version exists. Wear-carrying items only. |
| `has_souvenir` | `boolean` | Whether a Souvenir version exists. Wear-carrying items only. |
| `float_range` | `object` | Float bounds for this item. Wear-carrying items only. |
| `wear` | `string` | This item's wear (e.g. `Field-Tested`). Wear-carrying items only. |
| `wear_float_range` | `object` | Float bounds for this exact wear row, `float_range` clamped to this wear's bracket. Wear-carrying items only. |
| `stattrak` | `boolean` | Whether this row is the StatTrak version. |
| `souvenir` | `boolean` | Whether this row is the Souvenir version. |
| `variants` | `SchemaItemVariant[]` | Doppler / Gamma Doppler phases or Case Hardened tiers for this base item. |
| `variant` | `object` | Back-link on a variant row to its base item. |
| `phase` | `string` | Phase or gem name. Doppler and Gamma Doppler variant rows only. |
| `color` | `string` | Hex accent color. Doppler and Gamma Doppler variant rows only. |

### SchemaItemVariant

A Doppler / Gamma Doppler phase or Case Hardened tier listed under a base item's `variants`.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Required. Full variant `market_hash_name`. |
| `family` | `string` | Required. Allowed: `doppler`, `gamma_doppler`, `case_hardened`. Variant family. |
| `name` | `string` | Required. Variant name (e.g. `Phase 2`, `Ruby`, `Tier 1`). |
| `phase` | `string` | Phase or gem name. Omitted for Case Hardened. |
| `color` | `string` | Hex accent color. Omitted for Case Hardened. |
| `paint_index` | `integer` | Paint kit index for this variant. |
| `image` | `string` | Required. Owned image URL served from `cs2.sh`. |
| `steam_image` | `string` | Optional official Valve Economy/static image URL, emitted only when the exact variant origin is independently proven. Its absence does not remove the required owned `image`. |

### SchemaCollection

Collection metadata. Keyed by collection name in the top-level `collections` map.

| Field | Type | Description |
| --- | --- | --- |
| `name` | `string` | Required. Collection name. |
| `kind` | `string` | Required. Collection kind (e.g. `weapon`, `sticker`). |
| `release_date` | `string` | Release date (`YYYY-MM-DD`), when known. An item's release date is its collection's; items carry `collections`, so join on that rather than expecting a date per item. |
| `released_at` | `string` | Exact publication instant of the Valve announcement that shipped the collection (RFC 3339 UTC). Present only where that announcement is known. |
| `update_name` | `string` | Valve's own name for that update, e.g. `Season 5, Armory, and More`. |
| `announcement_url` | `string` | Canonical Steam announcement for that update. |
| `image` | `string` | Owned image URL served from `cs2.sh`, when available. |
| `steam_image` | `string` | Optional official Valve Economy/static image URL, emitted only when the exact origin is independently proven. |

### SchemaRarity

A rarity tier. Listed in the top-level `rarities` array and referenced by item-level `rarity`.

| Field | Type | Description |
| --- | --- | --- |
| `key` | `string` | Required. Stable rarity key (e.g. `ancient`, `legendary`). |
| `name` | `string` | Required. Display name (e.g. `Covert`, `Classified`). |
| `tier` | `integer` | Required. Numeric rarity tier, ascending with rarity. |
| `color` | `string` | Required. Hex color for the rarity. |

## Errors

| Status | When |
| --- | --- |
| `400` | Query parameters are not accepted, or `Accept-Encoding: gzip` is missing. |
| `401` | Missing or invalid key. |
| `429` | Rate-limited. |
| `503` / `5xx` | Catalog unavailable or server-side issue. |

---

# GET /health

Service health status.

No authentication required.

## Request

`GET https://api.cs2.sh/health`

**curl**

```bash
curl https://api.cs2.sh/health \
  -H "Accept-Encoding: gzip" --compressed
```

**Python**

```python
import requests

headers = {
    "Accept-Encoding": "gzip",
}

response = requests.get(
    "https://api.cs2.sh/health",
    headers=headers,
)

response.raise_for_status()
data = response.json()
```

**Node**

```javascript
const headers = {
  "Accept-Encoding": "gzip",
};

const response = await fetch("https://api.cs2.sh/health", { headers });

if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
```

**Go**

```go
package main

import (
    "io"
    "net/http"
)

func main() {
    req, _ := http.NewRequest("GET", "https://api.cs2.sh/health", nil)
    req.Header.Set("Accept-Encoding", "gzip")

    resp, err := http.DefaultClient.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    _, _ = io.ReadAll(resp.Body)
}
```

## Response

```json
{
  "status": "up",
  "last_refreshed_at": "2026-07-26T18:54:15.442085768Z",
  "schema_ready": true,
  "sources": {
    "buff": {
      "updated_at": "2026-07-26T18:50:49Z",
      "collected_at": "2026-07-26T18:53:10.67Z",
      "status": "up"
    },
    "c5game": {
      "updated_at": "2026-07-26T18:48:08.979Z",
      "collected_at": "2026-07-26T18:51:38.285Z",
      "status": "up"
    },
    "csfloat": {
      "updated_at": "2026-07-26T18:53:05.094Z",
      "collected_at": "2026-07-26T18:53:05.134Z",
      "status": "up"
    },
    "skinport": {
      "updated_at": "2026-07-26T18:53:09.397Z",
      "collected_at": "2026-07-26T18:53:15.672Z",
      "status": "up"
    },
    "steam": {
      "updated_at": "2026-07-26T18:52:08.812Z",
      "collected_at": "2026-07-26T18:52:54.624Z",
      "status": "up"
    },
    "youpin": {
      "updated_at": "2026-07-26T18:53:20.241Z",
      "collected_at": "2026-07-26T18:53:26.895Z",
      "status": "up"
    }
  },
  "variants": {
    "buff_variant": {
      "updated_at": "2026-07-26T18:50:48Z",
      "collected_at": "2026-07-26T18:53:10.67Z",
      "status": "up"
    },
    "c5game_variant": {
      "updated_at": "2026-07-26T18:47:01.827Z",
      "collected_at": "2026-07-26T18:51:38.285Z",
      "status": "up"
    },
    "csfloat_variant": {
      "updated_at": "2026-07-26T18:53:16.358Z",
      "collected_at": "2026-07-26T18:53:30.141Z",
      "status": "up"
    },
    "skinport_variant": {
      "updated_at": "2026-07-26T18:53:09.397Z",
      "collected_at": "2026-07-26T18:53:15.672Z",
      "status": "up"
    },
    "youpin_variant": {
      "updated_at": "2026-07-26T18:53:26.905Z",
      "collected_at": "2026-07-26T18:53:29.758Z",
      "status": "up"
    }
  },
  "endpoints": {
    "archive/csfloat": {
      "updated_at": "2026-07-26T00:00:00Z",
      "collected_at": "2026-07-26T18:53:56.265Z",
      "status": "up"
    },
    "archive/history": {
      "updated_at": "2026-07-26T03:59:39Z",
      "collected_at": "2026-07-26T04:01:52.044Z",
      "status": "up"
    },
    "archive/steam": {
      "updated_at": "2026-07-26T17:00:00Z",
      "collected_at": "2026-07-26T17:00:00Z",
      "status": "up"
    },
    "liquidity": {
      "updated_at": "2026-07-26T18:36:42Z",
      "collected_at": "2026-07-26T18:40:06.941Z",
      "status": "up"
    },
    "liquidity/items": {
      "updated_at": "2026-07-26T00:00:00Z",
      "collected_at": "2026-07-26T00:00:29.508Z",
      "status": "up"
    },
    "market/buff/history": {
      "updated_at": "2026-07-26T18:50:54.164Z",
      "collected_at": "2026-07-26T18:50:54.164Z",
      "status": "up"
    },
    "market/buff/latest": {
      "updated_at": "2026-07-26T18:50:54.164Z",
      "collected_at": "2026-07-26T18:50:54.164Z",
      "status": "up"
    },
    "market/steam/history": {
      "updated_at": "2026-07-26T18:00:00Z",
      "collected_at": "2026-07-26T18:00:00Z",
      "status": "up"
    },
    "market/steam/latest": {
      "updated_at": "2026-07-26T18:52:53.402Z",
      "collected_at": "2026-07-26T18:52:56.46Z",
      "status": "up"
    },
    "prices/history": {
      "updated_at": "2026-07-26T18:50:00Z",
      "collected_at": "2026-07-26T18:50:00Z",
      "status": "up"
    },
    "prices/latest": {
      "updated_at": "2026-07-26T18:53:16.358Z",
      "collected_at": "2026-07-26T18:53:30.141Z",
      "status": "up"
    },
    "schema": {
      "updated_at": "2026-07-20T22:44:41Z",
      "collected_at": "2026-07-26T05:30:26.938145778Z",
      "status": "up"
    }
  },
  "stats": {
    "total_events": 27426561632,
    "market_hash_names": 43906,
    "variant_items": 1372
  }
}
```

## Response fields

| Field | Type | Description |
| --- | --- | --- |
| `status` | `string` | Overall service status: `up`, `degraded`, or `down`. |
| `last_refreshed_at` | `string` | ISO timestamp. |
| `schema_ready` | `boolean` | Whether the schema artifacts loaded successfully (item validation ready and `GET /v1/schema` serving). |
| `sources` | `object` | Map of health entries. |
| `variants` | `object` | Map of health entries. |
| `endpoints` | `object` | Map of health entries. |
| `stats` | `object` | Aggregate counts. |

Health entries contain `updated_at`, `collected_at`, and `status`.

For `endpoints.schema`, `updated_at` is the immutable catalog's build time and
`collected_at` is when this API process loaded it. The pair is immutable for the
process lifetime; generation activation restarts the API instead of polling the
artifact.

`stats` contains `total_events`, `market_hash_names`, and `variant_items`.

---

# API Objects

Response object shapes used across the cs2.sh API.

Response object field reference for the cs2.sh API.

## Response Envelopes

### LatestPricesGetResponse

All-items snapshot. Returned by `GET /v1/prices/latest` with shared response metadata.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated |
| `currency` | `string` | Currency code (always `USD`) |
| `items` | `object` | Map of `market_hash_name` to item price data. |

### LatestPricesPostResponse

Filtered per-item snapshot. Returned by `POST /v1/prices/latest` – includes per-item `errors`.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated |
| `currency` | `string` | Currency code (always `USD`) |
| `items` | `object` | Map of `market_hash_name` to item price data, filtered to the requested items. |
| `errors` | `ItemError[]` | Per-item failures alongside successful results (partial success). |

### HistoryResponse

Response shape for `POST /v1/prices/history`.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated. |
| `currency` | `string` | Currency code (always `USD`). |
| `start` | `string (date-time)` | Effective start of the queried range, floored to the interval boundary. |
| `end` | `string (date-time)` | Effective end of the queried range, ceiled to the interval boundary. Exclusive. |
| `interval` | `string` | Allowed: `5m`, `30m`, `1h`, `1d`. OHLC bucket size. |
| `items` | `object` | Map of `market_hash_name` to OHLC time-series. |
| `errors` | `ItemError[]` | Per-item failures alongside successful results (partial success). |

### ItemLiquidityGetResponse

All-items liquidity snapshot. Returned by `GET /v1/liquidity/items`.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the snapshot was computed. |
| `run_date` | `string (date)` | UTC date for the daily computation. |
| `items` | `object` | Map of `market_hash_name` to item liquidity data. |

### LiquidityGetResponse

All-items liquidity snapshot. Returned by `GET /v1/liquidity` with shared response metadata.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated |
| `items` | `object` | Map of `market_hash_name` to liquidity data. |

### LiquidityPostResponse

Filtered per-item liquidity. Returned by `POST /v1/liquidity` – includes per-item `errors`.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated |
| `items` | `object` | Map of `market_hash_name` to liquidity data, filtered to the requested items. |
| `errors` | `ItemError[]` | Per-item failures alongside successful results (partial success). |

### BUFFMarketFloatLatestResponse

All-items BUFF market float/fade snapshot. Returned by `GET /v1/market/buff/latest`. Prices are converted USD only; raw CNY fields and BUFF internal lineage are not exposed.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated. |
| `currency` | `string` | Currency code (always `USD`). |
| `items` | `object` | Map of `market_hash_name` to per-item BUFF data. |

### BUFFMarketFloatHistoryResponse

Response shape for `POST /v1/market/buff/history`. Returns OHLC history for each requested BUFF market float/fade bucket.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated. |
| `currency` | `string` | Currency code (always `USD`). |
| `start` | `string (date-time)` | Effective start of the queried range, floored to the interval boundary. |
| `end` | `string (date-time)` | Effective end of the queried range, ceiled to the interval boundary. Exclusive. |
| `interval` | `string` | Allowed: `30m`, `1h`, `1d`. OHLC bucket size. |
| `items` | `object` | Map of `market_hash_name` to per-item BUFF history. |
| `errors` | `ItemError[]` | Per-item failures alongside successful results (partial success). |

### ArchiveCSFloatResponse

Response shape for `POST /v1/archive/csfloat`.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated. |
| `currency` | `string` | Currency code (always `USD`). |
| `start` | `string (date-time)` | Effective start of the queried range, floored to the day boundary. |
| `end` | `string (date-time)` | Effective end of the queried range, ceiled to the day boundary. Exclusive. |
| `items` | `object` | Map of `market_hash_name` to CSFloat sale time-series. |
| `errors` | `ItemError[]` | Per-item failures alongside successful results (partial success). |

### ArchiveHistoryResponse

Response shape for `POST /v1/archive/history`.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated. |
| `currency` | `string` | Currency code (always `USD`). |
| `start` | `string (date-time)` | Effective start of the queried range, floored to the interval boundary. |
| `end` | `string (date-time)` | Effective end of the queried range, ceiled to the interval boundary. Exclusive. |
| `interval` | `string` | Allowed: `1h`, `1d`. Archive bucket size. |
| `items` | `object` | Map of `market_hash_name` to archive time-series. |
| `errors` | `ItemError[]` | Per-item failures alongside successful results (partial success). |

### ArchiveSteamResponse

Response shape for `POST /v1/archive/steam`. Valid regular items with no rows return item-level `not_in_archive`; if every valid regular item has no rows, the endpoint returns `404 not_found`.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | Required. When the response was generated. |
| `currency` | `string` | Required. Currency code (always `USD`). |
| `start` | `string (date-time)` | Required. Normalized UTC inclusive start. |
| `end` | `string (date-time)` | Required. Normalized UTC exclusive end. |
| `interval` | `string` | Required. Allowed: `1h`, `1d`. Requested native Steam interval for every returned bucket. |
| `items` | `object` | Required. Map of `market_hash_name` to native Steam sale-history buckets. |
| `errors` | `ItemError[]` | Per-item failures alongside successful results (partial success). |

### ArchiveYoupinResponse

Response shape for `POST /v1/archive/youpin`.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | When the response was generated. |
| `currency` | `string` | Currency code (always `USD`). |
| `start` | `string (date-time)` | Effective start of the queried range, floored to the 1h boundary. |
| `end` | `string (date-time)` | Effective end of the queried range, ceiled to the 1h boundary. Exclusive. |
| `items` | `object` | Map of `market_hash_name` to Youpin sale series. |
| `errors` | `ItemError[]` | Per-item failures alongside successful results (partial success). |

### SteamOrderbookLatestResponse

All-items latest Steam orderbook snapshot. Returned by `GET /v1/market/steam/latest` from a pre-gzipped cache. No variants or internal lineage fields are exposed.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | Required. Cache serialization/build time. |
| `currency` | `string` | Required. Currency code (always `USD`). |
| `as_of` | `string (date-time)` | Required. Maximum selected `updated_at` across rows included in this cache snapshot. |
| `items` | `object` | Required. Fresh regular items keyed by `market_hash_name`. |

### SteamOrderbookHistoryResponse

Response shape for `POST /v1/market/steam/history`. Valid regular items with no rows are omitted; if all valid regular items have no rows, `items` is empty.

| Field | Type | Description |
| --- | --- | --- |
| `response_time` | `string (date-time)` | Required. When the response was generated. |
| `currency` | `string` | Required. Currency code (always `USD`). |
| `start` | `string (date-time)` | Required. Normalized UTC inclusive start. |
| `end` | `string (date-time)` | Required. Normalized UTC exclusive end. |
| `interval` | `string` | Required. Allowed: `1h`, `1d`. Requested bucket interval. |
| `items` | `object` | Required. Map of `market_hash_name` to returned orderbook history. |
| `errors` | `ItemError[]` | Per-item failures alongside successful results (partial success). |

### SchemaResponse

Response shape for `GET /v1/schema` – the full item catalog with metadata, keyed by `market_hash_name`.

| Field | Type | Description |
| --- | --- | --- |
| `schema_version` | `string` | Required. Catalog schema version. Re-sync clients when it changes. |
| `generation_id` | `string` | Required. Additive identifier for the immutable generation shared by the public API and site-data artifacts. |
| `generated_at` | `string (date-time)` | Required. When this immutable catalog generation was built. Use `generation_id` or the response ETag to detect a generation change. |
| `counts` | `object` | Required. Catalog entity counts. |
| `rarities` | `SchemaRarity[]` | Rarity tiers. |
| `collections` | `object` | Collection metadata keyed by collection name. |
| `items` | `object` | Required. Item records keyed by `market_hash_name`. |

## Items

### Item

Price data for an item across all sources.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Steam market hash name (the canonical item identifier). |
| `buff` | `BUFFSourceData` | Price data from BUFF. |
| `youpin` | `YoupinSourceData` | Price data from Youpin898. |
| `csfloat` | `CsfloatSourceData` | Current CSFloat listing and buy-order prices. |
| `skinport` | `SkinportSourceData` | Price data from Skinport, including Skinport-supplied rolling history windows. |
| `c5game` | `C5GameSourceData` | Price data from C5Game. Ask and bid come from independent collection passes – timestamps may differ for the same item. |
| `steam` | `SteamSourceData` | Price data from the Steam Community Market. |
| `variants` | `object` | Per-variant price data for items with Doppler / Gamma Doppler phases or Case Hardened tiers. Keyed by display name. |

### Variant

A variant of an item (Doppler / Gamma Doppler phase or Case Hardened tier). `youpin` includes `ask`, `bid`, and `bid_volume` on every Doppler and Gamma Doppler phase, with `ask_volume` on most items.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Base item `market_hash_name`. Full variant name: `name`. |
| `name` | `string` | The variant's full `market_hash_name`, e.g. `★ Karambit \| Doppler (Factory New) \| Phase 1`. |
| `display_name` | `string` | Human-readable variant label (e.g. `Phase 1`, `Ruby`, `Tier 1`, `Blue Gem`). |
| `version` | `string` | Allowed: `p1`, `p2`, `p3`, `p4`, `ruby`, `sapphire`, `blackpearl`, `emerald`, `t1`, `t2`, `t3`, `t4`, `singleblue`. Stable variant code. Switch on this in client code. |
| `buff` | `BUFFSourceData` | Price data from BUFF. |
| `youpin` | `YoupinSourceData` | Price data from Youpin898. |
| `csfloat` | `CsfloatSourceData` | Current CSFloat listing and buy-order prices. |
| `skinport` | `SkinportSourceData` | Price data from Skinport, including Skinport-supplied rolling history windows. |
| `c5game` | `C5GameSourceData` | Price data from C5Game. Ask and bid come from independent collection passes – timestamps may differ for the same item. |
| `steam` | `SteamSourceData` | Price data from the Steam Community Market. |

### HistoryItem

OHLC time-series for a single item.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Steam market hash name (the canonical item identifier). |
| `count` | `integer` | Number of buckets with data |
| `data` | `HistoryBucket[]` | OHLC buckets in chronological order. |
| `variants` | `object` | Per-variant OHLC time-series for items with Doppler / Gamma Doppler phases or Case Hardened tiers. Keyed by display name. |

### ItemLiquidityItem

Item liquidity bucket and estimated sale time for a single item.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Steam market hash name. |
| `liquidity` | `string` | Allowed: `unknown`, `extremely_illiquid`, `very_illiquid`, `illiquid`, `moderate`, `liquid`, `very_liquid`, `extremely_liquid`. Recomputed item liquidity bucket. |
| `estimated_sale_time` | `string` | Allowed: `under 1 hour`, `1 - 2 hours`, `2 - 6 hours`, `6 - 12 hours`, `12 - 24 hours`, `1 - 2 days`, `2 - 3 days`, `3 - 4 days`, `4 - 5 days`, `5 - 7 days`, `7 - 10 days`, `10 - 14 days`, `2 - 3 weeks`, `3 - 4 weeks`, `1 - 1.5 months`, `1.5 - 2 months`, `2+ months`, `unknown`. 80th-percentile estimated time for a competitively priced listing to sell. |
| `variants` | `object` | Per-variant item liquidity keyed by display name. |

### LiquidityItem

Liquidity rank for a single item. Items with insufficient trading activity have no rank.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Steam market hash name. |
| `liquidity_rank` | `number` | Percentile (0–100) of trading activity. Higher = more liquid. 90+ = top 10% most liquid. |
| `updated_at` | `string (date-time)` | When this rank was last updated. |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data. |
| `variants` | `object` | Per-variant liquidity for items with Doppler / Gamma Doppler phases or Case Hardened tiers. Keyed by display name. |

### BUFFMarketFloatItem

BUFF market float/fade data for one item.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Canonical base `market_hash_name`. |
| `buckets` | `BUFFMarketFloatLatestBucket[]` | Latest BUFF buckets for the base listing. |
| `variants` | `object` | Per-variant BUFF data for items with Doppler / Gamma Doppler phases or Case Hardened tiers. Keyed by display name (e.g. `Phase 1`, `Ruby`, `Tier 1`). |

### BUFFMarketFloatHistoryItem

BUFF market float/fade OHLC history for one item.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Canonical base `market_hash_name`. |
| `buckets` | `BUFFMarketFloatHistoryBucket[]` | OHLC history for the base listing's buckets. |
| `variants` | `object` | Per-variant OHLC history for items with Doppler / Gamma Doppler phases or Case Hardened tiers. Keyed by display name. |

### BUFFMarketFloatVariant

BUFF latest data for a single variant of an item (Doppler / Gamma Doppler phase or Case Hardened tier).

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Base item's `market_hash_name`. Full variant name lives in `name`. |
| `name` | `string` | The variant's full `market_hash_name`, e.g. `★ M9 Bayonet \| Doppler (Factory New) \| Phase 1`. |
| `display_name` | `string` | Human-readable variant label (e.g. `Phase 1`, `Ruby`, `Tier 1`). |
| `version` | `string` | Stable variant code. Switch on this in client code. |
| `buckets` | `BUFFMarketFloatLatestBucket[]` | Latest BUFF buckets for this variant. |

### BUFFMarketFloatHistoryVariant

BUFF OHLC history for a single variant of an item.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Base item's `market_hash_name`. Full variant name lives in `name`. |
| `name` | `string` | The variant's full `market_hash_name`, e.g. `★ M9 Bayonet \| Doppler (Factory New) \| Phase 1`. |
| `display_name` | `string` | Human-readable variant label. |
| `version` | `string` | Stable variant code. |
| `buckets` | `BUFFMarketFloatHistoryBucket[]` | OHLC history per bucket for this variant. |

### ArchiveCSFloatItem

CSFloat sale time-series for a single item.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Steam market hash name. |
| `count` | `integer` | Number of days with data |
| `data` | `ArchiveCSFloatBucket[]` | Daily sale aggregates in chronological order. |
| `variants` | `object` | Per-variant CSFloat sale time-series for items with Doppler / Gamma Doppler phases or Case Hardened tiers. Keyed by display name. |

### ArchiveHistoryItem

Long-term archive time-series for a single item.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Steam market hash name. |
| `count` | `integer` | Number of buckets with data. |
| `data` | `ArchiveHistoryBucket[]` | Archive buckets in chronological order. |
| `variants` | `object` | Per-variant archive time-series for items with Doppler / Gamma Doppler phases or Case Hardened tiers. Keyed by display name. |

### ArchiveSteamItem

Native Steam sale-history buckets for one regular item. No variants are returned.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Required. Canonical regular Steam market hash name. |
| `count` | `integer` | Required. Number of buckets in `data`. |
| `data` | `ArchiveSteamBucket[]` | Required. Buckets sorted ascending by `bucket`. |

### ArchiveYoupinItem

Youpin sale history for a single item, served as one independent series per provider sampling interval.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Steam market hash name. |
| `intervals` | `object` | Independent series keyed by provider sampling interval, emitted in `1h`, `4h`, `12h` order. A key is present only when that interval was observed inside the requested window, so an entry that exists only to carry requested variants returns `{}`. |
| `variants` | `object` | Per-variant Youpin sale history for items with Doppler or Gamma Doppler phases or Case Hardened tiers. Keyed by display name, and omitted when empty. A variant series never falls back to base history. |

### SteamOrderbookItem

Latest full-depth Steam orderbook for one regular item. No cent fields, item IDs, currency IDs, variants, or raw lineage fields are exposed.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | Required. Steam observation time selected for this orderbook. |
| `collected_at` | `string (date-time)` | Required. When cs2.sh collected or ingested the selected row. |
| `top` | `SteamOrderbookTop` | Required. Top-of-book best ask/bid for a Steam orderbook. Each field is `null` when that side is absent. |
| `depth` | `SteamOrderbookDepth` | Required. Full-depth Steam orderbook ladders in columnar form. |

### SteamOrderbookHistoryItem

Steam orderbook bucket snapshots for one regular item. No variants are returned.

| Field | Type | Description |
| --- | --- | --- |
| `count` | `integer` | Required. Number of points in `data`. |
| `data` | `SteamOrderbookHistoryPoint[]` | Required. Points sorted ascending by `bucket`. |

## History Buckets

### HistoryBucket

A single OHLC time bucket. `bucket` is the interval boundary (UTC-aligned, deterministic); `open_time`/`close_time` on each per-source object are the actual first/last observation timestamps inside it.

| Field | Type | Description |
| --- | --- | --- |
| `bucket` | `string (date-time)` | Start of the time bucket. UTC-aligned to the interval boundary (e.g. `2026-01-08T19:00:00Z` for an `1h` bucket). Deterministic. |
| `buff` | `BUFFOHLCSourceData` | OHLC bucket of BUFF prices. |
| `youpin` | `YoupinOHLCSourceData` | OHLC bucket of Youpin prices. |
| `csfloat` | `CsfloatOHLCSourceData` | OHLC bucket of CSFloat ask and bid prices. |
| `skinport` | `SkinportOHLCSourceData` | OHLC bucket of Skinport ask prices. |
| `c5game` | `C5GameOHLCSourceData` | OHLC bucket of C5Game ask and bid prices. |
| `steam` | `SteamOHLCSourceData` | OHLC bucket of Steam Community Market ask and bid prices. |

### BUFFMarketFloatLatestBucket

One latest BUFF market bucket. Buckets are stratified by `bucket_type` (`base`, `float`, `fade`, `float_fade`); raw CNY prices and BUFF internal lineage are not exposed.

| Field | Type | Description |
| --- | --- | --- |
| `bucket_id` | `string` | Stable bucket identifier (e.g. `base`, `float:0.15:0.18`, `variant:p2\|float:0.00:0.01`). |
| `bucket_type` | `string` | Allowed: `base`, `float`, `fade`, `float_fade`. Bucket stratification. - `base`: aggregated across the entire item or variant. - `float`: float-range slice (see `float`). - `fade`: fade-percentage slice (see `fade`). - `float_fade`: combined float and fade slice. |
| `float` | `BUFFMarketFloatRange` | Numeric range for a `float` or `fade` bucket. `min` is inclusive, `max` is exclusive. |
| `fade` | `BUFFMarketFloatRange` | Numeric range for a `float` or `fade` bucket. `min` is inclusive, `max` is exclusive. |
| `updated_at` | `string (date-time)` | When BUFF last refreshed this bucket. |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this bucket. |
| `ask` | `number` | Lowest ask price (USD) in this bucket. |
| `avg_ask` | `number` | Average ask price (USD) in the bucket. |
| `bid` | `number` | Highest buy-order price (USD) on BUFF. |
| `ask_volume` | `integer` | Number of items listed for sale in this bucket. |
| `bid_volume` | `integer` | Number of active buy orders against this bucket. |

### BUFFMarketFloatHistoryBucket

OHLC history for one BUFF market bucket. Each entry in `data` is one interval, in chronological order.

| Field | Type | Description |
| --- | --- | --- |
| `bucket_id` | `string` | Stable bucket identifier (e.g. `fade:99:100`, `variant:p2\|float:0.00:0.01`). |
| `bucket_type` | `string` | Allowed: `base`, `float`, `fade`, `float_fade`. Bucket stratification – see `BUFFMarketFloatLatestBucket.bucket_type`. |
| `float` | `BUFFMarketFloatRange` | Numeric range for a `float` or `fade` bucket. `min` is inclusive, `max` is exclusive. |
| `fade` | `BUFFMarketFloatRange` | Numeric range for a `float` or `fade` bucket. `min` is inclusive, `max` is exclusive. |
| `data` | `BUFFMarketFloatHistoryPoint[]` | OHLC observations for this bucket, chronological. |

### BUFFMarketFloatHistoryPoint

A single OHLC observation inside a BUFF market float/fade bucket history.

| Field | Type | Description |
| --- | --- | --- |
| `bucket` | `string (date-time)` | UTC-aligned start of the OHLC interval. |
| `updated_at` | `string (date-time)` | When BUFF last refreshed the bucket inside this interval. |
| `collected_at` | `string (date-time)` | When cs2.sh fetched the source rows inside this interval. |
| `open_ask` | `number` | First ask price (USD) observed in the interval. |
| `high_ask` | `number` | Highest ask price (USD) observed in the interval. |
| `low_ask` | `number` | Lowest ask price (USD) observed in the interval. |
| `close_ask` | `number` | Last ask price (USD) observed in the interval. |
| `open_avg_ask` | `number` | First `avg_ask` value observed in the interval. |
| `high_avg_ask` | `number` | Highest `avg_ask` value observed in the interval. |
| `low_avg_ask` | `number` | Lowest `avg_ask` value observed in the interval. |
| `close_avg_ask` | `number` | Last `avg_ask` value observed in the interval. |
| `open_bid` | `number` | First bid price (USD) observed in the interval. |
| `high_bid` | `number` | Highest bid price (USD) observed in the interval. |
| `low_bid` | `number` | Lowest bid price (USD) observed in the interval. |
| `close_bid` | `number` | Last bid price (USD) observed in the interval. |
| `ask_volume` | `integer` | Last observed ask volume inside the interval. |
| `bid_volume` | `integer` | Last observed bid volume inside the interval. |
| `open_time` | `string (date-time)` | Timestamp of the first observation inside the interval. Distinct from `bucket` (the interval boundary). |
| `close_time` | `string (date-time)` | Timestamp of the last observation inside the interval. Distinct from `bucket` (the interval boundary). |

### BUFFMarketFloatRange

Numeric range for a `float` or `fade` bucket. `min` is inclusive, `max` is exclusive.

| Field | Type | Description |
| --- | --- | --- |
| `min` | `number` | Inclusive lower bound. |
| `max` | `number` | Exclusive upper bound. |

### ArchiveCSFloatBucket

One day of sale data on CSFloat.

| Field | Type | Description |
| --- | --- | --- |
| `date` | `string` | Date in `YYYY-MM-DD` format (UTC). |
| `price` | `number` | Arithmetic average of all sale prices (USD) that day. |
| `volume` | `integer` | Number of sales that day. |

### ArchiveHistoryBucket

A single archive time bucket. Each platform key is present only when data exists for that platform in this bucket.

| Field | Type | Description |
| --- | --- | --- |
| `bucket` | `string (date-time)` | Start of the time bucket (UTC-aligned to the interval boundary). |
| `aggregate` | `ArchiveHistoryPlatformData` | Per-platform price data within an archive bucket. `hourly_volume` and `total_supply` are populated only on the `aggregate` platform. |
| `buff` | `ArchiveHistoryPlatformData` | Per-platform price data within an archive bucket. `hourly_volume` and `total_supply` are populated only on the `aggregate` platform. |
| `youpin` | `ArchiveHistoryPlatformData` | Per-platform price data within an archive bucket. `hourly_volume` and `total_supply` are populated only on the `aggregate` platform. |
| `c5game` | `ArchiveHistoryPlatformData` | Per-platform price data within an archive bucket. `hourly_volume` and `total_supply` are populated only on the `aggregate` platform. |

### ArchiveHistoryPlatformData

Per-platform price data within an archive bucket. `hourly_volume` and `total_supply` are populated only on the `aggregate` platform.

| Field | Type | Description |
| --- | --- | --- |
| `time` | `string (date-time)` | Actual timestamp of the last observation in the bucket. Distinct from the bucket boundary. |
| `ask` | `number` | Last observed ask price (USD) in the bucket. |
| `ask_volume` | `integer` | Last observed number of items listed for sale. |
| `bid` | `number` | Last observed bid price (USD) in the bucket. |
| `bid_volume` | `integer` | Last observed number of buy orders. |
| `hourly_volume` | `number` | Aggregated trading volume metric (`aggregate` platform only). |
| `total_supply` | `number` | Total market supply metric (`aggregate` platform only). |
| `sample_count` | `integer` | Number of observations aggregated into this bucket. |

### ArchiveSteamBucket

One native Steam sale-history bucket. `price` is Steam median sale price and `volume` is purchases.

| Field | Type | Description |
| --- | --- | --- |
| `bucket` | `string (date-time)` | Required. Native Steam bucket start. |
| `price` | `number` | Required. Steam median sale price in USD. |
| `volume` | `integer` | Required. Steam purchase count. |

### ArchiveYoupinSeries

One independent Youpin sale series at a single provider sampling interval, carrying exactly `count` and `data`. Series are never stitched, summed, or interleaved with one another.

| Field | Type | Description |
| --- | --- | --- |
| `count` | `integer` | Number of points in this series, equal to the length of `data`. This is not a sale volume, and `count` of 0 with an empty `data` means the interval was observed and no sales landed in the window. |
| `data` | `ArchiveYoupinPoint[]` | Sales at this interval, ordered by bucket. |

### ArchiveYoupinPoint

One sale on Youpin. Youpin keeps one sale per sampling bucket, so a point is a real sale, not an aggregate. The sampling interval is the series key, never a field on the point.

| Field | Type | Description |
| --- | --- | --- |
| `bucket` | `string (date-time)` | Start of the provider sampling bucket the point represents, at the width of the series holding it. |
| `time` | `string (date-time)` | Actual sale time inside the bucket. |
| `price` | `number` | Sale price (USD), converted from CNY at the sale date's own historical rate, or `null` when no rate for that date could be resolved. |

### SteamOrderbookTop

Top-of-book best ask/bid for a Steam orderbook. Each field is `null` when that side is absent.

| Field | Type | Description |
| --- | --- | --- |
| `ask` | `number` | Required. Best sell price in USD, or `null` when absent. |
| `ask_volume` | `integer` | Required. Total Steam sell-order count, or `null` when absent. |
| `bid` | `number` | Required. Best buy-order price in USD, or `null` when absent. |
| `bid_volume` | `integer` | Required. Total Steam buy-order count, or `null` when absent. |

### SteamOrderbookDepth

Full-depth Steam orderbook ladders in columnar form.

| Field | Type | Description |
| --- | --- | --- |
| `ask_levels` | `integer` | Required. Number of ask levels in `asks`. |
| `bid_levels` | `integer` | Required. Number of bid levels in `bids`. |
| `asks` | `SteamOrderbookDepthSide` | Required. One side of the orderbook ladder in columnar form. `prices[i]` pairs with `volumes[i]`; each `volume` is the quantity available at that exact price, not cumulative. |
| `bids` | `SteamOrderbookDepthSide` | Required. One side of the orderbook ladder in columnar form. `prices[i]` pairs with `volumes[i]`; each `volume` is the quantity available at that exact price, not cumulative. |

### SteamOrderbookDepthSide

One side of the orderbook ladder in columnar form. `prices[i]` pairs with `volumes[i]`; each `volume` is the quantity available at that exact price, not cumulative.

| Field | Type | Description |
| --- | --- | --- |
| `prices` | `number[]` | Required. Decimal USD prices. Asks ascending, bids descending. |
| `volumes` | `integer[]` | Required. Quantity available at each corresponding price. |

### SteamOrderbookHistoryPoint

One latest-in-bucket full-depth Steam orderbook snapshot. This is not OHLC data.

| Field | Type | Description |
| --- | --- | --- |
| `bucket` | `string (date-time)` | Required. UTC bucket start. |
| `updated_at` | `string (date-time)` | Required. Latest Steam observation selected inside this bucket. |
| `collected_at` | `string (date-time)` | Required. When cs2.sh collected or ingested the selected row. |
| `top` | `SteamOrderbookTop` | Required. Top-of-book best ask/bid for a Steam orderbook. Each field is `null` when that side is absent. |
| `depth` | `SteamOrderbookDepth` | Required. Full-depth Steam orderbook ladders in columnar form. |

## Latest Price Source Data

### BUFFSourceData

Price data from BUFF.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When BUFF last updated this price |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `bid` | `number` | Highest buy-order price (USD) |
| `bid_volume` | `integer` | Number of active buy orders |

### YoupinSourceData

Price data from Youpin898.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When Youpin last updated this price |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `bid` | `number` | Highest buy-order price (USD) |
| `bid_volume` | `integer` | Number of active buy orders |

### CsfloatSourceData

Current CSFloat listing and buy-order prices.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When CSFloat last updated this price |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `bid` | `number` | Highest buy-order price (USD) |

### SkinportSourceData

Price data from Skinport, including Skinport-supplied rolling history windows.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When Skinport last updated this price |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `max_ask` | `number` | Highest listing price (USD) |
| `mean_ask` | `number` | Average listing price (USD) |
| `median_ask` | `number` | Median listing price (USD) |
| `24h_history` | `SkinportPriceWindow` | Skinport-supplied rolling price window. Object is `null` when Skinport has no recent sales for the item. |
| `7d_history` | `SkinportPriceWindow` | Skinport-supplied rolling price window. Object is `null` when Skinport has no recent sales for the item. |
| `30d_history` | `SkinportPriceWindow` | Skinport-supplied rolling price window. Object is `null` when Skinport has no recent sales for the item. |
| `90d_history` | `SkinportPriceWindow` | Skinport-supplied rolling price window. Object is `null` when Skinport has no recent sales for the item. |

### SteamSourceData

Price data from the Steam Community Market.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When the upstream price was last updated |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `bid` | `number` | Highest buy-order price (USD) |
| `bid_volume` | `integer` | Number of active buy orders |

### C5GameSourceData

Price data from C5Game. Ask and bid come from independent collection passes – timestamps may differ for the same item.

| Field | Type | Description |
| --- | --- | --- |
| `updated_at` | `string (date-time)` | When C5Game last updated this price |
| `collected_at` | `string (date-time)` | When cs2.sh fetched this data |
| `ask` | `number` | Lowest ask price (USD) |
| `ask_volume` | `integer` | Number of items listed for sale |
| `bid` | `number` | Highest buy-order price (USD) |

### SkinportPriceWindow

Skinport-supplied rolling price window. Object is `null` when Skinport has no recent sales for the item.

| Field | Type | Description |
| --- | --- | --- |
| `price` | `number` | Last sale price (USD) within the window |
| `max_price` | `number` | Highest sale price (USD) within the window |
| `mean_price` | `number` | Average sale price (USD) within the window |
| `median_price` | `number` | Median sale price (USD) within the window |
| `volume` | `integer` | Number of sales within the window |

## OHLC Source Data

### BUFFOHLCSourceData

OHLC bucket of BUFF prices.

| Field | Type | Description |
| --- | --- | --- |
| `open_ask` | `number` | First ask price in the bucket |
| `high_ask` | `number` | Highest ask price in the bucket |
| `low_ask` | `number` | Lowest ask price in the bucket |
| `close_ask` | `number` | Last ask price in the bucket |
| `ask_volume` | `integer` | Last observed ask volume in the bucket |
| `open_bid` | `number` | First bid price in the bucket |
| `high_bid` | `number` | Highest bid price in the bucket |
| `low_bid` | `number` | Lowest bid price in the bucket |
| `close_bid` | `number` | Last bid price in the bucket |
| `bid_volume` | `integer` | Last observed bid volume in the bucket |
| `sample_count` | `integer` | Number of underlying 5-minute observations aggregated into this bucket |
| `open_time` | `string (date-time)` | Timestamp of the first observation inside this bucket. Distinct from `bucket` (the interval boundary). |
| `close_time` | `string (date-time)` | Timestamp of the last observation inside this bucket. Distinct from `bucket` (the interval boundary). |

### YoupinOHLCSourceData

OHLC bucket of Youpin prices.

| Field | Type | Description |
| --- | --- | --- |
| `open_ask` | `number` | First ask price in the bucket |
| `high_ask` | `number` | Highest ask price in the bucket |
| `low_ask` | `number` | Lowest ask price in the bucket |
| `close_ask` | `number` | Last ask price in the bucket |
| `ask_volume` | `integer` | Last observed ask volume in the bucket |
| `open_bid` | `number` | First bid price in the bucket |
| `high_bid` | `number` | Highest bid price in the bucket |
| `low_bid` | `number` | Lowest bid price in the bucket |
| `close_bid` | `number` | Last bid price in the bucket |
| `bid_volume` | `integer` | Last observed bid volume in the bucket |
| `sample_count` | `integer` | Number of underlying 5-minute observations aggregated into this bucket |
| `open_time` | `string (date-time)` | Timestamp of the first observation inside this bucket. Distinct from `bucket` (the interval boundary). |
| `close_time` | `string (date-time)` | Timestamp of the last observation inside this bucket. Distinct from `bucket` (the interval boundary). |

### CsfloatOHLCSourceData

OHLC bucket of CSFloat ask and bid prices.

| Field | Type | Description |
| --- | --- | --- |
| `open_ask` | `number` | First ask price in the bucket |
| `high_ask` | `number` | Highest ask price in the bucket |
| `low_ask` | `number` | Lowest ask price in the bucket |
| `close_ask` | `number` | Last ask price in the bucket |
| `ask_volume` | `integer` | Last observed ask volume in the bucket |
| `open_bid` | `number` | First bid price in the bucket |
| `high_bid` | `number` | Highest bid price in the bucket |
| `low_bid` | `number` | Lowest bid price in the bucket |
| `close_bid` | `number` | Last bid price in the bucket |
| `sample_count` | `integer` | Number of underlying 5-minute observations aggregated into this bucket |
| `open_time` | `string (date-time)` | Timestamp of the first observation inside this bucket. Distinct from `bucket` (the interval boundary). |
| `close_time` | `string (date-time)` | Timestamp of the last observation inside this bucket. Distinct from `bucket` (the interval boundary). |

### SkinportOHLCSourceData

OHLC bucket of Skinport ask prices.

| Field | Type | Description |
| --- | --- | --- |
| `open_ask` | `number` | First ask price in the bucket |
| `high_ask` | `number` | Highest ask price in the bucket |
| `low_ask` | `number` | Lowest ask price in the bucket |
| `close_ask` | `number` | Last ask price in the bucket |
| `ask_volume` | `integer` | Last observed ask volume in the bucket |
| `sample_count` | `integer` | Number of underlying 5-minute observations aggregated into this bucket |
| `open_time` | `string (date-time)` | Timestamp of the first observation inside this bucket. Distinct from `bucket` (the interval boundary). |
| `close_time` | `string (date-time)` | Timestamp of the last observation inside this bucket. Distinct from `bucket` (the interval boundary). |

### SteamOHLCSourceData

OHLC bucket of Steam Community Market ask and bid prices.

| Field | Type | Description |
| --- | --- | --- |
| `open_ask` | `number` | First ask price in the bucket |
| `high_ask` | `number` | Highest ask price in the bucket |
| `low_ask` | `number` | Lowest ask price in the bucket |
| `close_ask` | `number` | Last ask price in the bucket |
| `ask_volume` | `integer` | Last observed ask volume in the bucket |
| `open_bid` | `number` | First bid price in the bucket |
| `high_bid` | `number` | Highest bid price in the bucket |
| `low_bid` | `number` | Lowest bid price in the bucket |
| `close_bid` | `number` | Last bid price in the bucket |
| `bid_volume` | `integer` | Last observed bid volume in the bucket |
| `sample_count` | `integer` | Number of underlying 5-minute observations aggregated into this bucket |
| `open_time` | `string (date-time)` | Timestamp of the first observation inside this bucket. Distinct from `bucket` (the interval boundary). |
| `close_time` | `string (date-time)` | Timestamp of the last observation inside this bucket. Distinct from `bucket` (the interval boundary). |

### C5GameOHLCSourceData

OHLC bucket of C5Game ask and bid prices.

| Field | Type | Description |
| --- | --- | --- |
| `open_ask` | `number` | First ask price in the bucket |
| `high_ask` | `number` | Highest ask price in the bucket |
| `low_ask` | `number` | Lowest ask price in the bucket |
| `close_ask` | `number` | Last ask price in the bucket |
| `ask_volume` | `integer` | Last observed ask volume in the bucket |
| `open_bid` | `number` | First bid price in the bucket |
| `high_bid` | `number` | Highest bid price in the bucket |
| `low_bid` | `number` | Lowest bid price in the bucket |
| `close_bid` | `number` | Last bid price in the bucket |
| `sample_count` | `integer` | Number of underlying 5-minute observations aggregated into this bucket |
| `open_time` | `string (date-time)` | Timestamp of the first observation inside this bucket. Distinct from `bucket` (the interval boundary). |
| `close_time` | `string (date-time)` | Timestamp of the last observation inside this bucket. Distinct from `bucket` (the interval boundary). |

## Schema Catalog

### SchemaItem

One catalog record, keyed by `market_hash_name` in the top-level `items` map. Fields that do not apply to the item are omitted.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Required. Canonical Steam market hash name (matches the price endpoints). |
| `category` | `string` | Required. Item category (e.g. `skin`, `sticker`, `container`, `agent`). |
| `image` | `string` | Required. Owned image URL served from `cs2.sh`. |
| `steam_image` | `string` | Optional official Valve Economy/static image URL, emitted only when the exact item origin is independently proven. Its absence does not remove the required owned `image`. |
| `is_tradable` | `boolean` | Required. Whether the item can be traded. |
| `rarity` | `object` | Item rarity – `name`, `tier`, and `color`. |
| `collections` | `string[]` | Collections the item belongs to. Omitted when none. |
| `containers` | `string[]` | Containers the item drops from. Omitted when none. |
| `ids` | `object` | Marketplace catalog ids where known. |
| `def_index` | `integer` | Item definition index. |
| `base_name` | `string` | Base item name without the wear suffix. Skins only. |
| `weapon` | `string` | Weapon name. Skins only. |
| `finish` | `string` | Finish name. Skins only. |
| `paint_index` | `integer` | Paint kit index. Skins only; omitted on Doppler and Gamma Doppler base items. |
| `wears` | `string[]` | Wears the item exists in. Wear-carrying items only. |
| `has_stattrak` | `boolean` | Whether a StatTrak version exists. Wear-carrying items only. |
| `has_souvenir` | `boolean` | Whether a Souvenir version exists. Wear-carrying items only. |
| `float_range` | `object` | Float bounds for this item. Wear-carrying items only. |
| `wear` | `string` | This item's wear (e.g. `Field-Tested`). Wear-carrying items only. |
| `wear_float_range` | `object` | Float bounds for this exact wear row, `float_range` clamped to this wear's bracket. Wear-carrying items only. |
| `stattrak` | `boolean` | Whether this row is the StatTrak version. |
| `souvenir` | `boolean` | Whether this row is the Souvenir version. |
| `variants` | `SchemaItemVariant[]` | Doppler / Gamma Doppler phases or Case Hardened tiers for this base item. |
| `variant` | `object` | Back-link on a variant row to its base item. |
| `phase` | `string` | Phase or gem name. Doppler and Gamma Doppler variant rows only. |
| `color` | `string` | Hex accent color. Doppler and Gamma Doppler variant rows only. |

### SchemaItemVariant

A Doppler / Gamma Doppler phase or Case Hardened tier listed under a base item's `variants`.

| Field | Type | Description |
| --- | --- | --- |
| `market_hash_name` | `string` | Required. Full variant `market_hash_name`. |
| `family` | `string` | Required. Allowed: `doppler`, `gamma_doppler`, `case_hardened`. Variant family. |
| `name` | `string` | Required. Variant name (e.g. `Phase 2`, `Ruby`, `Tier 1`). |
| `phase` | `string` | Phase or gem name. Omitted for Case Hardened. |
| `color` | `string` | Hex accent color. Omitted for Case Hardened. |
| `paint_index` | `integer` | Paint kit index for this variant. |
| `image` | `string` | Required. Owned image URL served from `cs2.sh`. |
| `steam_image` | `string` | Optional official Valve Economy/static image URL, emitted only when the exact variant origin is independently proven. Its absence does not remove the required owned `image`. |

### SchemaCollection

Collection metadata. Keyed by collection name in the top-level `collections` map.

| Field | Type | Description |
| --- | --- | --- |
| `name` | `string` | Required. Collection name. |
| `kind` | `string` | Required. Collection kind (e.g. `weapon`, `sticker`). |
| `release_date` | `string` | Release date (`YYYY-MM-DD`), when known. An item's release date is its collection's; items carry `collections`, so join on that rather than expecting a date per item. |
| `released_at` | `string` | Exact publication instant of the Valve announcement that shipped the collection (RFC 3339 UTC). Present only where that announcement is known. |
| `update_name` | `string` | Valve's own name for that update, e.g. `Season 5, Armory, and More`. |
| `announcement_url` | `string` | Canonical Steam announcement for that update. |
| `image` | `string` | Owned image URL served from `cs2.sh`, when available. |
| `steam_image` | `string` | Optional official Valve Economy/static image URL, emitted only when the exact origin is independently proven. |

### SchemaRarity

A rarity tier. Listed in the top-level `rarities` array and referenced by item-level `rarity`.

| Field | Type | Description |
| --- | --- | --- |
| `key` | `string` | Required. Stable rarity key (e.g. `ancient`, `legendary`). |
| `name` | `string` | Required. Display name (e.g. `Covert`, `Classified`). |
| `tier` | `integer` | Required. Numeric rarity tier, ascending with rarity. |
| `color` | `string` | Required. Hex color for the rarity. |

## Errors

### ItemError

Error for a specific item in partial success response

| Field | Type | Description |
| --- | --- | --- |
| `item` | `string` | The requested item name that failed |
| `code` | `string` | Allowed: `unknown_item`, `not_in_cache`, `invalid_format`, `not_in_archive`, `unsupported_variant`. Error code |
| `message` | `string` | Human-readable error message |

### ErrorResponse

| Field | Type | Description |
| --- | --- | --- |
| `error` | `string` | Required. Error code (e.g., validation_error, unauthorized, rate_limited) |
| `message` | `string` | Required. Human-readable error message |
| `request_id` | `string (uuid)` | Unique request identifier for support |
| `details` | `object` | Additional error details (structure varies by error type) |
