# 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 purchase volume in Steam's native history buckets.

- Daily (`1d`) buckets from April 26, 2013
- Hourly (`1h`) buckets from May 9, 2026

This is the same data shown in the price graph on a Steam Community Market item page. Collection updates about 1-4x per day. Variants are not supported. Max 100 items per request.

## Access

Requires a Scale or Enterprise API key.

## Supported intervals

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

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

    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 = "2025-01-01",
  end = "2025-02-01",
  interval = "1d"
)

resp <- request("https://api.cs2.sh/v1/archive/steam") |>
  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`. 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 fields

[ArchiveSteamResponse](/docs/objects#archivesteamresponse) 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 native Steam interval for every returned bucket. |
| `items` | [`Record<string, ArchiveSteamItem>`](/docs/objects#archivesteamitem) | Yes | Map of `market_hash_name` to native Steam sale-history buckets. |
| `errors` | [ItemError[]](/docs/objects#itemerror) | No | Per-item failures alongside successful results (partial success). |

## Buckets

| Field | Description |
| --- | --- |
| `items.<name>.count` | Number of buckets with data. |
| `items.<name>.data[]` | Native Steam sale-history buckets. |
| `data[].bucket` | Bucket boundary. |
| `data[].price` | Steam's median sale price, USD. |
| `data[].volume` | Number of purchases in the bucket. |

- `bucket` is present on every bucket.
- `price` or `volume` can be `null` when Steam's native bucket omits that value.
- 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/objects#archivesteamitem), [ArchiveSteamBucket](/docs/objects#archivesteambucket).

### ArchiveSteamItem

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

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `market_hash_name` | `string` | Yes | Canonical regular Steam market hash name. |
| `count` | `integer` | Yes | Number of buckets in `data`. |
| `data` | [ArchiveSteamBucket[]](/docs/objects#archivesteambucket) | Yes | Buckets sorted ascending by `bucket`. |

### ArchiveSteamBucket

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

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

## Errors

`404 not_found` means none of the requested valid regular items have Steam archive rows. Partial results return `200` with `errors[]`; variant requests use `unsupported_variant`. See [Partial success](/docs/using-the-api#partial-success) and [Request errors](/docs/using-the-api#request-errors).
