# GET /health

服务健康状态。

返回市场来源、变体采集器、公共端点数据集、饰品 schema 和数据库汇总计数的当前健康状态。不需要认证。

健康数据就绪后，即使 JSON 中的 `status` 为 `degraded` 或 `down`，端点仍返回 HTTP `200`。HTTP `503` 表示健康快照本身尚未就绪。

## 请求

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

    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/health") |>
  req_headers(
    `Accept-Encoding` = "gzip"
  ) |>
  req_perform()

data <- resp_body_json(resp)
```

## 响应

```json
{
  "status": "up",
  "last_refreshed_at": "string",
  "schema_ready": false,
  "sources": null,
  "variants": null,
  "endpoints": null,
  "stats": {
    "total_events": 0,
    "market_hash_names": 0,
    "variant_items": 0
  }
}
```

## 响应字段

[HealthResponse](/zh-cn/docs/objects#healthresponse) 字段:

| 字段 | 类型 | 必需 | 描述 |
| --- | --- | --- | --- |
| `status` | `string` | 是 | 允许值: `up`, `degraded`, `down`. API 数据的整体健康状态。 |
| `last_refreshed_at` | `string (date-time)` | 是 | 此健康快照的生成时间。 |
| `schema_ready` | `boolean` | 是 | 饰品 schema 是否可用。 |
| `sources` | [`Record<string, HealthEntry>`](/zh-cn/docs/objects#healthentry) | 是 | 按来源键控的市场健康状态。 |
| `variants` | [`Record<string, HealthEntry>`](/zh-cn/docs/objects#healthentry) | 是 | 按来源采集器键控的变体价格健康状态。 |
| `endpoints` | [`Record<string, HealthEntry>`](/zh-cn/docs/objects#healthentry) | 是 | 按端点名称键控的数据集健康状态。 |
| `stats` | [HealthStats](/zh-cn/docs/objects#healthstats) | 是 | 上次健康状态刷新时的数据库汇总计数。 |

## 健康条目

`sources`、`variants` 和 `endpoints` 下的条目都包含 `updated_at`、`collected_at` 和 `status`。`status` 根据该数据集的预期刷新频率取值为 `up`、`degraded` 或 `down`。

`schema_ready` 表示 [GET /v1/schema](/zh-cn/docs/schema) 是否可用。`stats` 包含 `total_events`、`market_hash_names` 和 `variant_items`。

完整结构：[HealthEntry](/zh-cn/docs/objects#healthentry) 和 [HealthStats](/zh-cn/docs/objects#healthstats)。

### HealthEntry

单个来源、变体采集器或端点数据集的新鲜度和状态。

| 字段 | 类型 | 必需 | 描述 |
| --- | --- | --- | --- |
| `updated_at` | `string (date-time)` | 是 | 此条目所代表数据的最新来源时间。 |
| `collected_at` | `string (date-time)` | 是 | cs2.sh 最近采集或生成此数据集的时间。 |
| `status` | `string` | 是 | 允许值: `up`, `degraded`, `down`. 根据数据集预期刷新频率计算的健康状态。 |

### HealthStats

上次健康状态刷新时的数据库汇总计数。

| 字段 | 类型 | 必需 | 描述 |
| --- | --- | --- | --- |
| `total_events` | `integer` | 是 | 已存储的市场数据事件总数。 |
| `market_hash_names` | `integer` | 是 | 当前市场数据中唯一饰品名称的数量。 |
| `variant_items` | `integer` | 是 | 当前市场数据中唯一变体饰品名称的数量。 |
