# 快速开始

发起你的第一个 cs2.sh API 请求。

发起你的第一批 cs2.sh API 请求。本指南会获取饰品 schema、下载完整的最新价格快照，并介绍 BUFF 和 Steam 的专属快照。

## 获取 API 密钥

所有 `/v1` 端点都需要 API 密钥。

订阅套餐后，你可以在仪表盘中查看你的密钥。如果想先试用 API，请注册并在我们的 [Discord 服务器](https://discord.gg/5AJemzwBtq)开一个工单，获取免费的 2 天 Developer 密钥。

公开 API 基础 URL 为：

```text
https://api.cs2.sh
```

每个 `/v1` 请求都需要以下请求头：

| 请求头 | 值 |
| --- | --- |
| `Authorization` | `Bearer YOUR_API_KEY` |
| `Accept-Encoding` | `gzip` |

请把 API 密钥保存在你的后端。不要在浏览器或客户端代码中暴露它。

## 获取饰品 schema

`GET /v1/schema` 返回完整的 Counter-Strike 2 饰品 schema。

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

    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)

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

data <- resp_body_json(resp)
```

该 schema 包含约 47,500 件以 `market_hash_name` 为键的饰品，其中包括：

- 饰品类别和图片
- 稀有度和收藏品
- 外观和磨损区间
- 市场 id
- Doppler 变体

schema 与最新价格快照使用相同的键：

```text
schema.items["USP-S | Printstream (Factory New)"]
prices.items["USP-S | Printstream (Factory New)"]
```

这样你就可以用 schema 获取饰品元数据，用 `/v1/prices/latest` 获取当前市场价格，而无需维护自己的饰品名称映射。

schema 会在 Counter-Strike 2 游戏文件更新时自动更新。

关于所有可用的饰品元数据，见 [GET /v1/schema](/zh-cn/docs/schema)。

## 获取全部最新价格

`GET /v1/prices/latest` 返回每一件已收录饰品在每个受支持市场上的当前价格。

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

    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)

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

data <- resp_body_json(resp)
```

响应包含一个以 `market_hash_name` 为键的 `items` 对象。每件饰品对每个有可用数据的市场包含一个对象。

截断后的响应如下所示：

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

`ask` 是当前最低的出售挂单价。`bid` 是当前最高的普通求购价。`ask_volume` 和 `bid_volume` 是活跃挂单或求购订单的数量。

`updated_at` 是市场最后一次更新价格的时间。`collected_at` 是 cs2.sh 采集它的时间。

所有价格均以 USD 返回。

此端点返回每一件已收录的饰品，因此响应可能很大。当你需要反复查询价格时，请从后端下载并缓存它。

关于每个市场的字段和完整的响应 schema，见 [GET /v1/prices/latest](/zh-cn/docs/prices-latest)。

## 市场专属快照

通用的最新价格快照包含各市场当前的最优价格和数量。专属端点提供额外的市场特定数据。

### BUFF 磨损与渐变区间

`GET /v1/market/buff/latest` 返回按磨损区间拆分的 BUFF 价格。

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

    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)

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

data <- resp_body_json(resp)
```

每个区间都有自己的 ask、bid、挂单数量和求购订单数量。Doppler 和 Case Hardened 变体可以拥有自己的区间。

关于可用的区间类型和响应字段，见 [GET /v1/market/buff/latest](/zh-cn/docs/market-buff-latest)。

### Steam 订单簿

`GET /v1/market/steam/latest` 返回每一件已收录常规饰品的最新完整 Steam 买/卖订单簿。

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

    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)

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

data <- resp_body_json(resp)
```

响应包含最优买价和卖价，以及完整的订单簿深度。卖价按从低到高排序，买价按从高到低排序。

该快照约 100 MB。请从后端下载并缓存它，而不是为单个饰品查询而请求它。

Steam 不区分单独的 Doppler 或 Case Hardened 变体，因此不包含变体。

关于完整的订单簿格式，见 [GET /v1/market/steam/latest](/zh-cn/docs/market-steam-latest)。

## 获取指定饰品

如果你只需要一组已知饰品的当前价格，请改用 [POST /v1/prices/latest](/zh-cn/docs/prices-latest#post-v1priceslatest)。它接受最多 100 个 `market_hash_name` 值，并为这些饰品返回相同的市场价格对象。

## 下一步

- 阅读[数据覆盖范围](/zh-cn/docs/data-coverage)，了解支持的市场、可用字段、刷新频率、变体和历史覆盖范围。
- 阅读[使用 API](/zh-cn/docs/using-the-api)，了解共享的请求约定、时间戳、缺失数据、部分成功、错误和限制。
- 使用[交互式 API 演示](/zh-cn/demo)，无需编写代码即可查看响应。
