# Using the API

Everything shared across cs2.sh endpoints: authentication, item naming and variants, the response envelope, partial success, OHLC buckets, and the shared error and limit model.

This page covers the conventions shared across cs2.sh API endpoints, including authentication, request types, response objects, variants, timestamps, missing data, partial success, errors, and limits.

- For a guided first request, start with the [Quickstart](/docs/quickstart).
- For marketplace fields, refresh rates, and historical coverage, see [Data Coverage](/docs/data-coverage).
- Individual endpoint pages document their exact parameters and response fields.

## Authentication

The public API base URL is `https://api.cs2.sh`.

All `/v1` endpoints require a Bearer API key. Every `/v1` request must also accept gzip compression, and POST requests should also include `Content-Type: application/json`:

| Header | Value | Required for |
| --- | --- | --- |
| `Authorization` | `Bearer YOUR_API_KEY` | All `/v1` endpoints |
| `Accept-Encoding` | `gzip` | All `/v1` endpoints |
| `Content-Type` | `application/json` | POST endpoints |

Successful `/v1` responses are gzip-encoded. Most HTTP clients decompress them automatically. Error responses are returned as plain JSON.

Rotating your API key from the dashboard generates a new key and immediately invalidates the old one.

## GET and POST requests

cs2.sh uses two main request patterns:

- GET snapshot: fetch the complete current dataset for an endpoint.
- POST query: request data for up to 100 specific items, with endpoint-specific parameters such as dates, sources, or intervals.

For example, this fetches the complete current price snapshot:

```http
GET /v1/prices/latest
```

This fetches current prices for two specific items:

```http
POST /v1/prices/latest
Content-Type: application/json

{
  "items": [
    "USP-S | Printstream (Factory New)",
    "AK-47 | Redline (Field-Tested)"
  ]
}
```

GET snapshots can be large, but are useful since you can save a single response and perform future lookups locally. POST requests are better when you need a bounded response for a known set of items. These are also used for history endpoints to limit response size.

## Items

POST endpoints identify items using `market_hash_name`:

```json
{
  "items": [
    "USP-S | Printstream (Factory New)"
  ]
}
```

[GET /v1/schema](/docs/schema) returns every supported item by the same `market_hash_name` accepted by all endpoints. It also contains item metadata, marketplace ids, images, wears, float ranges, and variants.

POST endpoints accept up to 100 items in one request.

## Responses

Most item endpoints return an `items` object keyed by `market_hash_name`.

```json
{
  "response_time": "2026-07-26T18:54:04.041Z",
  "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
      }
    }
  }
}
```

Common top-level fields include:

| Field | Meaning |
| --- | --- |
| `response_time` | When the API generated the response. |
| `currency` | Response currency, currently only `USD` for price data. |
| `items` | Map of item names to the returned data. |
| `errors` | Per-item failures returned alongside successful items on POST endpoints. |

Current-price items contain one object per marketplace. Historical endpoints use the same `items` map, with time-series data nested inside each item.

See [API Objects](/docs/objects) for the complete response schemas.

## Variants

Items with supported Doppler, Gamma Doppler, or Case Hardened variants can include a `variants` object.

```json
{
  "market_hash_name": "★ Karambit | Doppler (Factory New)",
  "buff": {
    "ask": 1336.26,
    "bid": 1281.77
  },
  "variants": {
    "Ruby": {
      "market_hash_name": "★ Karambit | Doppler (Factory New)",
      "name": "★ Karambit | Doppler (Factory New) | Ruby",
      "display_name": "Ruby",
      "version": "ruby",
      "buff": {
        "ask": 7671.41,
        "bid": 7287.47
      },
      "csfloat": {
        "ask": 7590,
        "bid": 7220
      }
    }
  }
}
```

On a variant object:

| Field | Meaning |
| --- | --- |
| `market_hash_name` | The base item's market hash name. |
| `name` | The full cs2.sh variant name. |
| `display_name` | Human-readable variant label. |
| `version` | Stable variant code. |

### Version codes

Supported `version` codes for variant items:

| Version code | Variant family | Display label |
| --- | --- | --- |
| `p1` | Doppler / Gamma Doppler | Phase 1 |
| `p2` | Doppler / Gamma Doppler | Phase 2 |
| `p3` | Doppler / Gamma Doppler | Phase 3 |
| `p4` | Doppler / Gamma Doppler | Phase 4 |
| `ruby` | Doppler | Ruby |
| `sapphire` | Doppler | Sapphire |
| `blackpearl` | Doppler | Black Pearl |
| `emerald` | Gamma Doppler | Emerald |
| `t1` | Case Hardened | Tier 1 |
| `t2` | Case Hardened | Tier 2 |
| `t3` | Case Hardened | Tier 3 |
| `t4` | Case Hardened | Tier 4 |
| `singleblue` | Case Hardened | Blue Gem |

Variant availability depends on the marketplace and endpoint. See [Data Coverage](/docs/data-coverage) for variant support and [GET /v1/schema](/docs/schema) for the variants attached to each item.

## Timestamps

Current marketplace price objects can include three different timestamps:

| Field | Meaning |
| --- | --- |
| `response_time` | When cs2.sh generated the complete API response. |
| `updated_at` | When the marketplace last updated the price. |
| `collected_at` | When cs2.sh collected it. |

`response_time` does not indicate when an individual marketplace price was collected. Use the timestamps inside that marketplace's object when checking freshness.

Refresh rates are approximate and differ by marketplace. See [Data Coverage](/docs/data-coverage) for the expected refresh rate of each endpoint and source.

## Historical response buckets

`prices/history` and `market/buff/history` return fixed, UTC-aligned OHLC buckets. Each marketplace object inside a bucket includes the following observation fields:

| Field | Meaning |
| --- | --- |
| `bucket` | Start of the UTC-aligned interval. |
| `open_time` | Time of the first observation inside the bucket. |
| `close_time` | Time of the last observation inside the bucket. |
| `sample_count` | Number of underlying observations represented by the bucket. |

`ask_volume` and `bid_volume` are the last observed values inside the bucket.

Not every historical endpoint returns OHLC. `market/steam/history` returns sampled Steam orderbook history, while archive endpoints return the data documented on their individual endpoint pages. See [Data Coverage](/docs/data-coverage) for the difference between OHLC, sampled, and archive history.

## Missing data

A missing price is not a price of zero.

On current-price base items, marketplace objects can be present with unavailable fields set to `null`:

```json
{
  "skinport": {
    "updated_at": null,
    "collected_at": null,
    "ask": null,
    "ask_volume": null
  }
}
```

Variant and historical response objects can be sparse. A marketplace object may be absent when that marketplace has no data for the variant or interval.

Some historical endpoints omit a valid item when no data exists inside the requested range. The relevant endpoint page documents its exact empty-data behavior.

## Partial success

POST endpoints validate requested items independently. A request can return successful items and per-item errors in the same `200` response.

```json
{
  "items": {
    "USP-S | Printstream (Factory New)": {
      "market_hash_name": "USP-S | Printstream (Factory New)"
    }
  },
  "errors": [
    {
      "item": "Invalid Item Name",
      "code": "unknown_item",
      "message": "item not found"
    }
  ]
}
```

An entry in `errors` applies only to that requested item. It does not invalidate the items returned successfully.

### Item error codes

| Code | Meaning |
| --- | --- |
| `unknown_item` | The requested name does not match a known item. |
| `invalid_format` | The submitted item value is not valid. |
| `not_in_cache` | The item is valid but unavailable in the relevant current dataset. |
| `not_in_archive` | The item is valid but has no rows in the requested archive dataset. |
| `unsupported_source` | The item has no identity on the requested marketplace. |
| `unsupported_variant` | The requested variant is not supported by that dataset. |

The relevant endpoint page documents which item-error codes it can return. See [ItemError](/docs/objects#itemerror) for the complete object.

Item errors are different from request-level errors.

## Request errors

Request-level errors use a shared JSON object:

```json
{
  "error": "validation_error",
  "message": "items must contain at most 100 entries",
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

Some errors also include a `details` object.

`request_id` identifies the failed request and should be included when contacting support.

| Status | Meaning |
| --- | --- |
| `400` | Missing or invalid request parameters, malformed JSON, or an oversized request. |
| `401` | Missing, malformed, or invalid API key. |
| `403` | The requested endpoint is not included in your plan. |
| `404` | Unknown path, or no requested item has data in the relevant dataset. |
| `405` | The endpoint does not support the requested HTTP method. |
| `429` | The per-second request limit was exceeded. |
| `500` | Internal server error. |
| `503` | The service, database, or requested snapshot is temporarily unavailable. |
| `504` | The request or database query timed out. |

Correct `400`, `401`, `403`, `404`, and `405` errors before retrying. Retry `429` and temporary `5xx` errors with a bounded delay.

Individual endpoint pages document any additional error behavior specific to that endpoint.

## Limits

| Limit | Value |
| --- | --- |
| Requests | 10 requests per second, per user |
| Items per POST request | 100 |
| Request body | 1 MiB |
| Response compression | gzip required for `/v1` |

Historical endpoints also have interval-specific maximum request ranges. These are documented in [Data Coverage](/docs/data-coverage) and on the relevant endpoint page.

The complete GET snapshots can be large. Cache them when you need repeated access to the same current dataset, and use POST endpoints for smaller item-specific requests.

## OpenAPI

The complete OpenAPI 3.1 specification is available at [cs2.sh/openapi.yaml](https://cs2.sh/openapi.yaml).

It contains the request parameters, response schemas, enums, and examples used by the endpoint reference.
