# 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/market-steam-latest). Data begins on June 9, 2026. Max 100 items per request.

Each bucket contains the last complete orderbook collected inside that interval. This is sampled history, not OHLC.

## Access

Requires a Scale or Enterprise API key.

## Supported intervals

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

## 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"
    "compress/gzip"
    "encoding/json"
    "fmt"
    "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()

    if resp.StatusCode < 200 || resp.StatusCode >= 300 {
        body, _ := io.ReadAll(resp.Body)
        panic(fmt.Sprintf("HTTP %d: %s", resp.StatusCode, body))
    }

    var reader io.Reader = resp.Body
    if resp.Header.Get("Content-Encoding") == "gzip" {
        gz, err := gzip.NewReader(resp.Body)
        if err != nil { panic(err) }
        defer gz.Close()
        reader = gz
    }

    var data any
    if err := json.NewDecoder(reader).Decode(&data); err != nil { panic(err) }
    fmt.Printf("%#v\n", data)
}
```

**R**

```r
library(httr2)

payload <- list(
  items = list(
    "USP-S | Printstream (Factory New)"
  ),
  start = "2026-07-20",
  end = "2026-07-23",
  interval = "1h"
)

resp <- request("https://api.cs2.sh/v1/market/steam/history") |>
  req_headers(
    Authorization = "Bearer <<YOUR_API_KEY>>",
    `Accept-Encoding` = "gzip"
  ) |>
  req_body_json(payload) |>
  req_perform()

data <- resp_body_json(resp)
```

## 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 fields

[SteamOrderbookHistoryResponse](/docs/objects#steamorderbookhistoryresponse) fields:

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

## Sampled buckets

| Field | Description |
| --- | --- |
| `items.<name>.count` | Number of buckets with data. |
| `items.<name>.data[]` | Orderbook snapshots: the latest full-depth observation inside each `bucket`. |
| `data[].bucket` | UTC interval boundary. |
| `data[].top` | Best ask/bid prices and total Steam ask/bid order counts. |
| `data[].depth` | Full columnar ask and bid ladders, same shape as `GET /v1/market/steam/latest`. |
| `data[].updated_at`, `collected_at` | Steam's update time and cs2.sh's fetch time. |

- Variant items are not included.
- Valid requested items with no buckets in the range are omitted from `items`.

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

### SteamOrderbookHistoryItem

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

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `count` | `integer` | Yes | Number of points in `data`. |
| `data` | [SteamOrderbookHistoryPoint[]](/docs/objects#steamorderbookhistorypoint) | Yes | Points sorted ascending by `bucket`. |

### SteamOrderbookHistoryPoint

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

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `bucket` | `string (date-time)` | Yes | UTC bucket start. |
| `updated_at` | `string (date-time)` | Yes | When Steam last updated the orderbook represented by this bucket. |
| `collected_at` | `string (date-time)` | Yes | When cs2.sh collected the orderbook represented by this bucket. |
| `top` | [SteamOrderbookTop](/docs/objects#steamorderbooktop) | Yes | Top-of-book best ask/bid for a Steam orderbook. Each field is `null` when that side is absent. |
| `depth` | [SteamOrderbookDepth](/docs/objects#steamorderbookdepth) | Yes | 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 | Required | Description |
| --- | --- | --- | --- |
| `ask` | `number \| null` | Yes | Best sell price in USD, or `null` when absent. |
| `ask_volume` | `integer \| null` | Yes | Total Steam sell-order count, or `null` when absent. |
| `bid` | `number \| null` | Yes | Best buy-order price in USD, or `null` when absent. |
| `bid_volume` | `integer \| null` | Yes | Total Steam buy-order count, or `null` when absent. |

### SteamOrderbookDepth

Full-depth Steam orderbook ladders in columnar form.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `ask_levels` | `integer` | Yes | Number of ask levels in `asks`. |
| `bid_levels` | `integer` | Yes | Number of bid levels in `bids`. |
| `asks` | [SteamOrderbookDepthSide](/docs/objects#steamorderbookdepthside) | Yes | 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](/docs/objects#steamorderbookdepthside) | Yes | 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 | Required | Description |
| --- | --- | --- | --- |
| `prices` | `number[]` | Yes | Decimal USD prices. Asks ascending, bids descending. |
| `volumes` | `integer[]` | Yes | Quantity available at each corresponding price. |

## Errors

When only some item names fail, the endpoint returns `200` with the successful series and `errors[]`. Variant requests use `unsupported_variant`; valid regular items with no buckets are omitted from `items`. See [Partial success](/docs/using-the-api#partial-success) and [Request errors](/docs/using-the-api#request-errors).
