# POST /v1/prices/history

自 2025 年 12 月 24 日以来持续更新的 CS2 饰品 OHLC 价格历史。

返回从与[最新价格](/zh-cn/docs/prices-latest)相同的快照聚合而成的高频 OHLC（开盘价、最高价、最低价、收盘价）价格历史。历史覆盖始于 2025 年 12 月 24 日。每次请求最多 100 个饰品。

具有 Doppler、Gamma Doppler 或 Case Hardened 历史的饰品可以包含 `variants`。

## 访问

需要 Scale 或 Enterprise API 密钥。

## 支持的间隔

| 间隔 | 最大范围 |
| --- | --- |
| `5m` | 14 天 |
| `30m` | 90 天 |
| `1h` | 365 天 |
| `1d` | 不限 |

## 支持的来源

| 来源 | 字段 |
| --- | --- |
| `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` |

默认返回全部来源。

`bucket` 是 UTC 间隔边界。`open_time` 和 `close_time` 是分桶内实际第一次和最后一次观测时间；见[使用 API](/zh-cn/docs/using-the-api#历史响应分桶)。

## 请求

`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"
    "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",
        "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()

    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",
  sources = list(
    "buff",
    "csfloat"
  ),
  interval = "1h"
)

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

data <- resp_body_json(resp)
```

## 参数

| 字段 | 类型 | 必需 | 描述 |
| --- | --- | --- | --- |
| `items` | `string[]` | 是 | `market_hash_name` 值列表（最多 100 个） |
| `start` | `string` | 是 | 开始日期（YYYY-MM-DD 或 RFC3339） |
| `end` | `string` | 否 | 结束日期（YYYY-MM-DD 或 RFC3339）。默认：现在 |
| `sources` | `string[]` | 否 | 过滤到指定来源。默认：全部来源 |
| `interval` | `string` | 否 | 默认值: `5m`. 允许值: `5m`, `30m`, `1h`, `1d`. 聚合间隔 |

## 响应

```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"
          }
        }
      ]
    }
  }
}
```

## 响应字段

[HistoryResponse](/zh-cn/docs/objects#historyresponse) 字段:

| 字段 | 类型 | 必需 | 描述 |
| --- | --- | --- | --- |
| `response_time` | `string (date-time)` | 是 | 响应生成时间。 |
| `currency` | `string` | 是 | 货币代码（始终为 `USD`）。 |
| `start` | `string (date-time)` | 是 | 查询范围的有效开始时间，向下取整到间隔边界。 |
| `end` | `string (date-time)` | 是 | 查询范围的有效结束时间，向上取整到间隔边界。不包含该时间。 |
| `interval` | `string` | 是 | 允许值: `5m`, `30m`, `1h`, `1d`. OHLC 分桶大小。 |
| `items` | [`Record<string, HistoryItem>`](/zh-cn/docs/objects#historyitem) | 是 | `market_hash_name` 到 OHLC 时间序列的映射。 |
| `errors` | [ItemError[]](/zh-cn/docs/objects#itemerror) | 否 | 与成功结果一起返回的逐饰品失败（部分成功）。 |

## 分桶

| 字段 | 描述 |
| --- | --- |
| `items.<name>.count` | 有数据的分桶数。 |
| `items.<name>.data[]` | OHLC 分桶。 |
| `data[].bucket` | UTC 对齐的间隔边界。 |
| `data[].<source>` | OHLC 值，加上真实观测窗口（`open_time`/`close_time`）和 `sample_count`。 |
| `items.<name>.variants` | 每个变体的相同分桶结构。 |

- 每个历史分桶上都存在 `bucket`。
- 来源对象仅在该来源在该分桶中有数据时出现。
- `csfloat` 包含 ask 与 bid OHLC，但没有 `bid_volume`；`skinport` 仅有卖价。
- 在请求区间内没有分桶的有效请求饰品会从 `items` 中省略。

完整结构：[HistoryItem](/zh-cn/docs/objects#historyitem)、[HistoryBucket](/zh-cn/docs/objects#historybucket)，以及 [OHLC 来源数据](/zh-cn/docs/objects#ohlc-来源数据) 下的各来源类型。

### HistoryItem

单个饰品的 OHLC 时间序列。

| 字段 | 类型 | 必需 | 描述 |
| --- | --- | --- | --- |
| `market_hash_name` | `string` | 是 | Steam 市场哈希名称（规范饰品标识符）。 |
| `count` | `integer` | 是 | 有数据的分桶数量 |
| `data` | [HistoryBucket[]](/zh-cn/docs/objects#historybucket) | 是 | 按时间顺序排列的 OHLC 分桶。 |
| `variants` | `Record<string, object>` | 否 | 带有 Doppler / Gamma Doppler 相位或 Case Hardened 分层的饰品的逐变体 OHLC 时间序列。按显示名称作为键。 |

### HistoryBucket

单个 OHLC 时间分桶。`bucket` 是间隔边界（UTC 对齐、确定性）；每个按来源对象上的 `open_time`/`close_time` 是其中实际第一次/最后一次观测时间戳。

| 字段 | 类型 | 必需 | 描述 |
| --- | --- | --- | --- |
| `bucket` | `string (date-time)` | 是 | 时间分桶的开始时间。UTC 对齐到间隔边界（例如 `1h` 分桶的 `2026-01-08T19:00:00Z`）。确定性。 |
| `buff` | [BUFFOHLCSourceData](/zh-cn/docs/objects#buffohlcsourcedata) | 否 | BUFF 价格的 OHLC 分桶。 |
| `youpin` | [YoupinOHLCSourceData](/zh-cn/docs/objects#youpinohlcsourcedata) | 否 | Youpin 价格的 OHLC 分桶。 |
| `csfloat` | [CsfloatOHLCSourceData](/zh-cn/docs/objects#csfloatohlcsourcedata) | 否 | CSFloat ask 与 bid 价格的 OHLC 分桶。 |
| `skinport` | [SkinportOHLCSourceData](/zh-cn/docs/objects#skinportohlcsourcedata) | 否 | Skinport ask 价格的 OHLC 分桶。 |
| `c5game` | [C5GameOHLCSourceData](/zh-cn/docs/objects#c5gameohlcsourcedata) | 否 | C5Game ask 和 bid 价格的 OHLC 分桶。 |
| `steam` | [SteamOHLCSourceData](/zh-cn/docs/objects#steamohlcsourcedata) | 否 | Steam Community Market ask 和 bid 价格的 OHLC 分桶。 |

## OHLC 来源数据

### BUFFOHLCSourceData

BUFF 价格的 OHLC 分桶。

| 字段 | 类型 | 必需 | 描述 |
| --- | --- | --- | --- |
| `open_ask` | `number \| null` | 是 | 分桶内第一个 ask 价格 |
| `high_ask` | `number \| null` | 是 | 分桶内最高 ask 价格 |
| `low_ask` | `number \| null` | 是 | 分桶内最低 ask 价格 |
| `close_ask` | `number \| null` | 是 | 分桶内最后一个 ask 价格 |
| `ask_volume` | `integer \| null` | 是 | 分桶内最后观测到的 ask 成交量 |
| `open_bid` | `number \| null` | 是 | 分桶内第一个 bid 价格 |
| `high_bid` | `number \| null` | 是 | 分桶内最高 bid 价格 |
| `low_bid` | `number \| null` | 是 | 分桶内最低 bid 价格 |
| `close_bid` | `number \| null` | 是 | 分桶内最后一个 bid 价格 |
| `bid_volume` | `integer \| null` | 是 | 分桶内最后观测到的 bid 成交量 |
| `sample_count` | `integer` | 是 | 聚合到此分桶的底层 5 分钟观测数量 |
| `open_time` | `string (date-time) \| null` | 是 | 此分桶内第一次观测的时间戳。不同于 `bucket`（间隔边界）。 |
| `close_time` | `string (date-time) \| null` | 是 | 此分桶内最后一次观测的时间戳。不同于 `bucket`（间隔边界）。 |

### YoupinOHLCSourceData

Youpin 价格的 OHLC 分桶。

| 字段 | 类型 | 必需 | 描述 |
| --- | --- | --- | --- |
| `open_ask` | `number \| null` | 是 | 分桶内第一个 ask 价格 |
| `high_ask` | `number \| null` | 是 | 分桶内最高 ask 价格 |
| `low_ask` | `number \| null` | 是 | 分桶内最低 ask 价格 |
| `close_ask` | `number \| null` | 是 | 分桶内最后一个 ask 价格 |
| `ask_volume` | `integer \| null` | 是 | 分桶内最后观测到的 ask 成交量 |
| `open_bid` | `number \| null` | 是 | 分桶内第一个 bid 价格 |
| `high_bid` | `number \| null` | 是 | 分桶内最高 bid 价格 |
| `low_bid` | `number \| null` | 是 | 分桶内最低 bid 价格 |
| `close_bid` | `number \| null` | 是 | 分桶内最后一个 bid 价格 |
| `bid_volume` | `integer \| null` | 是 | 分桶内最后观测到的 bid 成交量 |
| `sample_count` | `integer` | 是 | 聚合到此分桶的底层 5 分钟观测数量 |
| `open_time` | `string (date-time) \| null` | 是 | 此分桶内第一次观测的时间戳。不同于 `bucket`（间隔边界）。 |
| `close_time` | `string (date-time) \| null` | 是 | 此分桶内最后一次观测的时间戳。不同于 `bucket`（间隔边界）。 |

### CsfloatOHLCSourceData

CSFloat ask 与 bid 价格的 OHLC 分桶。

| 字段 | 类型 | 必需 | 描述 |
| --- | --- | --- | --- |
| `open_ask` | `number \| null` | 是 | 分桶内第一个 ask 价格 |
| `high_ask` | `number \| null` | 是 | 分桶内最高 ask 价格 |
| `low_ask` | `number \| null` | 是 | 分桶内最低 ask 价格 |
| `close_ask` | `number \| null` | 是 | 分桶内最后一个 ask 价格 |
| `ask_volume` | `integer \| null` | 是 | 分桶内最后观测到的 ask 成交量 |
| `open_bid` | `number \| null` | 是 | 分桶内第一个 bid 价格 |
| `high_bid` | `number \| null` | 是 | 分桶内最高 bid 价格 |
| `low_bid` | `number \| null` | 是 | 分桶内最低 bid 价格 |
| `close_bid` | `number \| null` | 是 | 分桶内最后一个 bid 价格 |
| `sample_count` | `integer` | 是 | 聚合到此分桶的底层 5 分钟观测数量 |
| `open_time` | `string (date-time) \| null` | 是 | 此分桶内第一次观测的时间戳。不同于 `bucket`（间隔边界）。 |
| `close_time` | `string (date-time) \| null` | 是 | 此分桶内最后一次观测的时间戳。不同于 `bucket`（间隔边界）。 |

### SkinportOHLCSourceData

Skinport ask 价格的 OHLC 分桶。

| 字段 | 类型 | 必需 | 描述 |
| --- | --- | --- | --- |
| `open_ask` | `number \| null` | 是 | 分桶内第一个 ask 价格 |
| `high_ask` | `number \| null` | 是 | 分桶内最高 ask 价格 |
| `low_ask` | `number \| null` | 是 | 分桶内最低 ask 价格 |
| `close_ask` | `number \| null` | 是 | 分桶内最后一个 ask 价格 |
| `ask_volume` | `integer \| null` | 是 | 分桶内最后观测到的 ask 成交量 |
| `sample_count` | `integer` | 是 | 聚合到此分桶的底层 5 分钟观测数量 |
| `open_time` | `string (date-time) \| null` | 是 | 此分桶内第一次观测的时间戳。不同于 `bucket`（间隔边界）。 |
| `close_time` | `string (date-time) \| null` | 是 | 此分桶内最后一次观测的时间戳。不同于 `bucket`（间隔边界）。 |

### SteamOHLCSourceData

Steam Community Market ask 和 bid 价格的 OHLC 分桶。

| 字段 | 类型 | 必需 | 描述 |
| --- | --- | --- | --- |
| `open_ask` | `number \| null` | 是 | 分桶内第一个 ask 价格 |
| `high_ask` | `number \| null` | 是 | 分桶内最高 ask 价格 |
| `low_ask` | `number \| null` | 是 | 分桶内最低 ask 价格 |
| `close_ask` | `number \| null` | 是 | 分桶内最后一个 ask 价格 |
| `ask_volume` | `integer \| null` | 是 | 分桶内最后观测到的 ask 成交量 |
| `open_bid` | `number \| null` | 是 | 分桶内第一个 bid 价格 |
| `high_bid` | `number \| null` | 是 | 分桶内最高 bid 价格 |
| `low_bid` | `number \| null` | 是 | 分桶内最低 bid 价格 |
| `close_bid` | `number \| null` | 是 | 分桶内最后一个 bid 价格 |
| `bid_volume` | `integer \| null` | 是 | 分桶内最后观测到的 bid 成交量 |
| `sample_count` | `integer` | 是 | 聚合到此分桶的底层 5 分钟观测数量 |
| `open_time` | `string (date-time) \| null` | 是 | 此分桶内第一次观测的时间戳。不同于 `bucket`（间隔边界）。 |
| `close_time` | `string (date-time) \| null` | 是 | 此分桶内最后一次观测的时间戳。不同于 `bucket`（间隔边界）。 |

### C5GameOHLCSourceData

C5Game ask 和 bid 价格的 OHLC 分桶。

| 字段 | 类型 | 必需 | 描述 |
| --- | --- | --- | --- |
| `open_ask` | `number \| null` | 是 | 分桶内第一个 ask 价格 |
| `high_ask` | `number \| null` | 是 | 分桶内最高 ask 价格 |
| `low_ask` | `number \| null` | 是 | 分桶内最低 ask 价格 |
| `close_ask` | `number \| null` | 是 | 分桶内最后一个 ask 价格 |
| `ask_volume` | `integer \| null` | 是 | 分桶内最后观测到的 ask 成交量 |
| `open_bid` | `number \| null` | 是 | 分桶内第一个 bid 价格 |
| `high_bid` | `number \| null` | 是 | 分桶内最高 bid 价格 |
| `low_bid` | `number \| null` | 是 | 分桶内最低 bid 价格 |
| `close_bid` | `number \| null` | 是 | 分桶内最后一个 bid 价格 |
| `sample_count` | `integer` | 是 | 聚合到此分桶的底层 5 分钟观测数量 |
| `open_time` | `string (date-time) \| null` | 是 | 此分桶内第一次观测的时间戳。不同于 `bucket`（间隔边界）。 |
| `close_time` | `string (date-time) \| null` | 是 | 此分桶内最后一次观测的时间戳。不同于 `bucket`（间隔边界）。 |

## 错误

如果只有部分饰品名称失败，端点仍返回 `200`，其中包含成功的序列和 `errors[]`。请求范围内没有分桶的有效饰品会从 `items` 中省略，不会产生饰品错误。见[部分成功](/zh-cn/docs/using-the-api#部分成功)和[请求错误](/zh-cn/docs/using-the-api#请求错误)。
