# POST /v1/market/csfloat/orderbook/history

CSFloat buy-order book snapshots over time.

Returns CSFloat buy order snapshots over time (daily or hourly intervals). This endpoint is the same shape as [GET /v1/market/csfloat/orderbook/latest](/docs/csfloat-orderbook-latest).

Data begins on August 10, 2026. Max 100 items per request.

Each interval contains the newest data observed inside that interval. For example, requesting the 1h interval would return the *newest* data for that hour.

## Access

Requires a Scale or Enterprise API key.

## Supported intervals

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

## Request

`POST https://api.cs2.sh/v1/market/csfloat/orderbook/history`

**curl**

```bash
curl -X POST https://api.cs2.sh/v1/market/csfloat/orderbook/history \
  -H "Authorization: Bearer <<YOUR_API_KEY>>" \
  -H "Accept-Encoding: gzip" --compressed \
  -H "Content-Type: application/json" \
  -d '{
  "items": [
    "★ Karambit | Doppler (Factory New)"
  ],
  "start": "2026-08-10",
  "end": "2026-08-23",
  "interval": "1h"
}'
```

**Python**

```python
import requests

headers = {
    "Authorization": "Bearer <<YOUR_API_KEY>>",
    "Accept-Encoding": "gzip",
    "Content-Type": "application/json",
}

payload = {
    "items": ["★ Karambit | Doppler (Factory New)"],
    "start": "2026-08-10",
    "end": "2026-08-23",
    "interval": "1h",
}

response = requests.post(
    "https://api.cs2.sh/v1/market/csfloat/orderbook/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/csfloat/orderbook/history", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "items": [
      "★ Karambit | Doppler (Factory New)"
    ],
    "start": "2026-08-10",
    "end": "2026-08-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{
            "★ Karambit | Doppler (Factory New)",
        },
        "start": "2026-08-10",
        "end": "2026-08-23",
        "interval": "1h",
    }
    body, _ := json.Marshal(payload)
    req, _ := http.NewRequest("POST", "https://api.cs2.sh/v1/market/csfloat/orderbook/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(
    "★ Karambit | Doppler (Factory New)"
  ),
  start = "2026-08-10",
  end = "2026-08-23",
  interval = "1h"
)

resp <- request("https://api.cs2.sh/v1/market/csfloat/orderbook/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 base or Doppler/Gamma Doppler phase `market_hash_name` values (max 100). |
| `start` | `string` | No | Start date/time as YYYY-MM-DD or RFC3339, inclusive. Data begins 2026-08-10. |
| `end` | `string` | No | End date/time as YYYY-MM-DD or RFC3339, exclusive. Defaults to now. |
| `interval` | `string` | No | Default: `1h`. Allowed: `1h`, `1d`. Bucket interval. `1h` is limited to 365 days; `1d` is unlimited. |

## Response

```json
{
  "response_time": "2026-08-23T22:00:11.929760469Z",
  "currency": "USD",
  "start": "2026-08-20T00:00:00Z",
  "end": "2026-08-22T00:00:00Z",
  "interval": "1h",
  "items": {
    "★ Karambit | Doppler (Factory New)": {
      "market_hash_name": "★ Karambit | Doppler (Factory New)",
      "count": 48,
      "data": [
        {
          "bucket": "2026-08-20T00:00:00Z",
          "updated_at": "2026-08-20T00:55:11.258Z",
          "collected_at": "2026-08-20T00:56:10.301Z",
          "top_generic_bid": null,
          "orders": [
            {
              "price": 6550,
              "quantity": 1,
              "kind": "paint_index",
              "conditions": {
                "paint_index": 417
              }
            },
            {
              "price": 4290,
              "quantity": 1,
              "kind": "paint_index",
              "conditions": {
                "paint_index": 416
              }
            }
          ]
        }
      ],
      "variants": {
        "Phase 2": {
          "market_hash_name": "★ Karambit | Doppler (Factory New)",
          "name": "★ Karambit | Doppler (Factory New) | Phase 2",
          "display_name": "Phase 2",
          "version": "p2",
          "count": 46,
          "data": [
            {
              "bucket": "2026-08-20T00:00:00Z",
              "updated_at": "2026-08-20T00:57:14.824Z",
              "collected_at": "2026-08-20T00:58:10.396Z",
              "top_generic_bid": 1230,
              "orders": [
                {
                  "price": 1630,
                  "quantity": 1,
                  "kind": "paint_index",
                  "conditions": {
                    "paint_index": 419
                  }
                },
                {
                  "price": 1620,
                  "quantity": 1,
                  "kind": "paint_index",
                  "conditions": {
                    "paint_index": 419
                  }
                }
              ]
            }
          ]
        }
      }
    }
  }
}
```

## Response fields

[CSFloatBuyOrdersHistoryResponse](/docs/objects#csfloatbuyordershistoryresponse) 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 | Effective start of the queried range, floored to the interval boundary. Inclusive. |
| `end` | `string (date-time)` | Yes | Effective end of the queried range, ceiled to the interval boundary. Exclusive. |
| `interval` | `string` | Yes | Allowed: `1h`, `1d`. Requested bucket interval. |
| `items` | [`Record<string, CSFloatBuyOrdersHistoryItem>`](/docs/objects#csfloatbuyordershistoryitem) | Yes | Map of `market_hash_name` to returned buy-order book 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[]` | Buy-order books: the newest observation inside each `bucket`. |
| `items.<name>.variants` | Doppler and Gamma Doppler phase series, keyed by display name. |
| `data[].orders` | The buy-order ladder, price descending, same shape as `GET /v1/market/csfloat/orderbook/latest`. |
| `data[].top_generic_bid` | Highest order price with no conditions; `null` when only conditional orders stand. |
| `data[].updated_at`, `collected_at` | CSFloat's update time and cs2.sh's fetch time. |

- A request naming only a phase (e.g. `★ Karambit | Doppler (Factory New) | Phase 2`) returns that phase nested under its base entry.

## Buy-order conditions

| `kind` | Meaning |
| --- | --- |
| `generic` | No conditions. `conditions` is `{}`. |
| `paint_index` | The listing's paint index must match. |
| `float` | The listing's float value must be within the supplied bounds. |
| `sticker` | The listing must have the specified sticker requirements. |
| `keychain_pattern` | The applied charm's pattern value must be within the supplied bounds. |
| `paint_seeds` | The listing's paint seed must be one of the supplied values. |
| `keychain` | The listing must have the specified charm. |
| `mixed` | The listing must satisfy all supplied condition families. |

| `conditions` key | Type | Meaning |
| --- | --- | --- |
| `paint_index` | `integer` | The listing's paint index must equal this value. |
| `min_float` | `number` | The listing's float value must be at least this value. |
| `max_float` | `number` | The listing's float value must be at most this value. |
| `stickers` | [`CSFloatStickerCondition[]`](/docs/objects#csfloatstickercondition) | The listing must satisfy every sticker requirement. Repeating an `sId` requires multiple copies. |
| `min_keychain_pattern` | `integer` | The applied charm's pattern value must be at least this value. |
| `max_keychain_pattern` | `integer` | The applied charm's pattern value must be at most this value. |
| `paint_seeds` | `integer[]` | The listing's paint seed must equal one of these values. |
| `keychains` | [`CSFloatKeychainCondition[]`](/docs/objects#csfloatkeychaincondition) | The listing must have every charm identified in this array. |

If multiple condition fields are present, the listing must satisfy all of them. `mixed` orders can also include additional CSFloat condition keys verbatim.

Sticker requirement:

| Field | Type | Required | Meaning |
| --- | --- | --- | --- |
| `sId` | `integer` | Yes | Numeric CSFloat ID of the sticker the listing must have. |
| `s` | `integer` | No | Zero-based slot that must contain this sticker. If omitted, the sticker may be in any slot. |

Charm requirement:

| Field | Type | Required | Meaning |
| --- | --- | --- | --- |
| `sId` | `integer` | Yes | Numeric CSFloat ID of the charm the listing must have. |

Full schemas: [CSFloatBuyOrdersHistoryItem](/docs/objects#csfloatbuyordershistoryitem), [CSFloatBuyOrdersHistoryVariant](/docs/objects#csfloatbuyordershistoryvariant), [CSFloatBuyOrdersHistoryPoint](/docs/objects#csfloatbuyordershistorypoint), [CSFloatBuyOrder](/docs/objects#csfloatbuyorder), [CSFloatBuyOrderConditions](/docs/objects#csfloatbuyorderconditions), [CSFloatStickerCondition](/docs/objects#csfloatstickercondition), [CSFloatKeychainCondition](/docs/objects#csfloatkeychaincondition).

### CSFloatBuyOrdersHistoryItem

CSFloat buy-order book history for one base item. Phase series nest under `variants`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `market_hash_name` | `string` | Yes | Canonical Steam `market_hash_name`. |
| `count` | `integer` | Yes | Number of points in `data`. |
| `data` | [CSFloatBuyOrdersHistoryPoint[]](/docs/objects#csfloatbuyordershistorypoint) | Yes | Points in chronological order. |
| `variants` | [`Record<string, CSFloatBuyOrdersHistoryVariant>`](/docs/objects#csfloatbuyordershistoryvariant) | No | Doppler and Gamma Doppler phase series keyed by display name. |

### CSFloatBuyOrdersHistoryVariant

CSFloat buy-order book history for one Doppler or Gamma Doppler phase.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `market_hash_name` | `string` | Yes | The base item's `market_hash_name`. The full variant name is `name`. |
| `name` | `string` | Yes | The variant's full `market_hash_name`, e.g. `★ Karambit \| Doppler (Factory New) \| Phase 1`. |
| `display_name` | `string` | Yes | Human-readable variant label (e.g. `Phase 2`, `Ruby`). |
| `version` | `string` | Yes | Stable variant code. Switch on this in client code. |
| `count` | `integer` | Yes | Number of points in `data`. |
| `data` | [CSFloatBuyOrdersHistoryPoint[]](/docs/objects#csfloatbuyordershistorypoint) | Yes | Points in chronological order. |

### CSFloatBuyOrdersHistoryPoint

The newest buy-order book observed in one UTC bucket. This is point-in-time book state, not OHLC data.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `bucket` | `string (date-time)` | Yes | UTC bucket start. |
| `updated_at` | `string (date-time)` | Yes | When CSFloat last updated the book represented by this bucket. |
| `collected_at` | `string (date-time)` | Yes | When cs2.sh collected the book represented by this bucket. |
| `top_generic_bid` | `number \| null` | Yes | Highest order price (USD) with no conditions. `null` when only conditional orders stand. |
| `orders` | [CSFloatBuyOrder[]](/docs/objects#csfloatbuyorder) | Yes | Price-descending order ladder. |

### CSFloatBuyOrder

One standing CSFloat buy order. Its conditions live in `conditions`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `price` | `number` | Yes | Order price in USD. |
| `quantity` | `integer` | No | Number of items wanted at this price. |
| `kind` | `string` | Yes | Allowed: `generic`, `paint_index`, `float`, `sticker`, `keychain_pattern`, `paint_seeds`, `keychain`, `mixed`. Summary of the matching rules in `conditions`. `generic` has no rules; `mixed` contains multiple rule families or an upstream rule the API does not recognize. |
| `conditions` | [CSFloatBuyOrderConditions](/docs/objects#csfloatbuyorderconditions) | Yes | Rules a listing must satisfy for this order to buy it. When several rules are present, all must match. Empty for `generic` orders. A `mixed` order can also carry unrecognized CSFloat rule keys verbatim. |

### CSFloatBuyOrderConditions

Rules a listing must satisfy for this order to buy it. When several rules are present, all must match. Empty for `generic` orders. A `mixed` order can also carry unrecognized CSFloat rule keys verbatim.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `paint_index` | `integer` | No | The listing's paint index must equal this value. |
| `min_float` | `number` | No | The listing's float value must be greater than or equal to this value. |
| `max_float` | `number` | No | The listing's float value must be less than or equal to this value. |
| `stickers` | [CSFloatStickerCondition[]](/docs/objects#csfloatstickercondition) | No | The listing must satisfy every sticker requirement in this array. Repeating a sticker ID requires multiple copies of that sticker. |
| `min_keychain_pattern` | `integer` | No | The applied charm's pattern value must be greater than or equal to this value. |
| `max_keychain_pattern` | `integer` | No | The applied charm's pattern value must be less than or equal to this value. |
| `paint_seeds` | `integer[]` | No | The listing's paint seed must equal one of these values. |
| `keychains` | [CSFloatKeychainCondition[]](/docs/objects#csfloatkeychaincondition) | No | The listing must have every charm identified in this array. |

### CSFloatStickerCondition

One sticker the listing must have. Additional upstream CSFloat fields are preserved.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `sId` | `integer` | Yes | Numeric CSFloat ID of the sticker the listing must have. |
| `s` | `integer` | No | Zero-based slot that must contain this sticker. If omitted, the sticker may be in any slot. |

### CSFloatKeychainCondition

One charm the listing must have. Additional upstream CSFloat fields are preserved.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `sId` | `integer` | Yes | Numeric CSFloat ID of the charm the listing must have. |

## Errors

When only some item names fail, the endpoint returns `200` with the successful series and `errors[]`. Variants without a CSFloat paint index (Marble Fade, Case Hardened, and other pattern-priced families) use `unsupported_variant`. See [Partial success](/docs/using-the-api#partial-success) and [Request errors](/docs/using-the-api#request-errors).
