Рыночные данные
GET /v1/prices/snapshot.ndjson.gz — полный снимок цен
Скачайте полный каталог цен CSBoard в виде gzip-сжатого NDJSON. По одному PriceRow на строку. Спроектировано под массовую загрузку с условными запросами по ETag.
GET
/
prices
/
snapshot.ndjson.gz
Full price-list snapshot (gzipped NDJSON)
curl --request GET \
--url https://csboard.com/v1/prices/snapshot.ndjson.gz \
--header 'Authorization: Bearer <token>'import requests
url = "https://csboard.com/v1/prices/snapshot.ndjson.gz"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://csboard.com/v1/prices/snapshot.ndjson.gz', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://csboard.com/v1/prices/snapshot.ndjson.gz",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://csboard.com/v1/prices/snapshot.ndjson.gz"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://csboard.com/v1/prices/snapshot.ndjson.gz")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://csboard.com/v1/prices/snapshot.ndjson.gz")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body"<string>"{
"code": "missing_api_key",
"detail": "Provide your API key via `Authorization: Bearer csb_pub_…`. Generate one at https://csboard.com/profile?tab=api"
}{
"code": "rate_limit_exceeded",
"detail": "Rate limit of 100 requests/min exceeded."
}Эндпоинт snapshot отдаёт полный список цен CSBoard в виде одного gzip-сжатого файла NDJSON. Каждая распакованная строка — это один JSON-объект
Пример распакованного вывода:
Ответ
PriceRow, той же схемы, что возвращает GET /v1/prices. Это рекомендуемый путь для потребителей полного каталога: сайтов сравнения, арбитражных ботов или дата-пайплайнов, которым нужна полная локальная копия списка цен. Для точечных запросов по подмножеству товаров используйте GET /v1/prices.
Требуется аутентификация. Отправьте ключ как Authorization: Bearer csb_pub_....
Лимит запросов: 1 запрос в минуту, отдельно от общего лимита 30 запросов/мин. Планируйте интервал опроса соответствующе.
Заголовки запроса
string
Передайте значение
ETag из предыдущего ответа snapshot, чтобы сделать условный запрос. Если снимок не изменился с момента этого ETag, сервер вернёт 304 Not Modified без тела, экономя трафик и избегая повторной загрузки.Заголовки ответа
| Заголовок | Описание |
|---|---|
ETag | Непрозрачная строка версии, идентифицирующая этот снимок. Сохраните её и отправьте обратно в If-None-Match при следующем запросе. |
Content-Encoding | gzip — тело всегда сжато gzip. |
Тело ответа
Поток, сжатый gzip. После распаковки каждая строка (разделитель — перевод строки) представляет собой валидный JSON-объект, соответствующий схемеPriceRow:
| Поле | Тип | Описание |
|---|---|---|
market_hash_name | string | Steam market hash name. |
wear | string | null | Диапазон износа или null. |
doppler_phase | string | null | Фаза Doppler или null. |
min_price_usd | number | Самая дешёвая текущая цена продажи в USD. |
qty | integer | Количество листингов в этой группе. |
Пример: загрузка и просмотр
curl https://csboard.com/v1/prices/snapshot.ndjson.gz \
-H "Authorization: Bearer csb_pub_..." \
--output snapshot.ndjson.gz \
&& gunzip -c snapshot.ndjson.gz | head -5
{"market_hash_name":"AK-47 | Redline (Field-Tested)","wear":"Field-Tested","doppler_phase":null,"min_price_usd":11.92,"qty":73}
{"market_hash_name":"AWP | Asiimov (Field-Tested)","wear":"Field-Tested","doppler_phase":null,"min_price_usd":54.20,"qty":12}
{"market_hash_name":"Karambit | Doppler (Factory New)","wear":"Factory New","doppler_phase":"Ruby","min_price_usd":1240.00,"qty":1}
Пример: условный запрос с ETag
При первой загрузке вы получаете заголовокETag. Передавайте его обратно в последующих запросах, чтобы не скачивать неизменённый снимок повторно:
# Первый запрос — сохраните ETag из заголовков ответа
curl https://csboard.com/v1/prices/snapshot.ndjson.gz \
-H "Authorization: Bearer csb_pub_..." \
--dump-header headers.txt \
--output snapshot.ndjson.gz
# Последующий запрос — условная загрузка
curl https://csboard.com/v1/prices/snapshot.ndjson.gz \
-H "Authorization: Bearer csb_pub_..." \
-H "If-None-Match: \"etag-value\"" \
--output snapshot.ndjson.gz
304 Not Modified означает, что снимок идентичен уже имеющемуся у вас — повторная загрузка не нужна.
Коды ошибок
| HTTP-статус | Код | Значение |
|---|---|---|
| 304 | (без тела) | Снимок не изменился с переданного If-None-Match ETag. |
| 401 | missing_api_key, invalid_api_key | Отсутствует или некорректный API-ключ. |
| 429 | snapshot_rate_limited | Превышен отдельный лимит снимка — 1 запрос/мин. Подождите перед повтором. |
Всегда сохраняйте
ETag из каждой успешной загрузки и отправляйте его обратно в If-None-Match при следующем запросе. Ответ 304 не расходует квоту лимита запросов и позволяет поддерживать локальную копию в актуальном состоянии без лишних повторных загрузок.Этот эндпоинт предназначен для массовой загрузки полного каталога. Если вам нужны цены только для конкретного товара или отфильтрованного подмножества, используйте
GET /v1/prices — он поддерживает фильтры по search, category и wear и не учитывается в лимите snapshot.Авторизации
Send your key as a Bearer token on every request: Authorization: Bearer csb_pub_.... Generate keys in your CSBoard profile.
Заголовки
Conditional request. Pass the ETag from a previous snapshot to receive 304 if unchanged.
Ответ
Gzipped NDJSON stream. Each decompressed line is one PriceRow JSON object. Sets an ETag header.
The response is of type file.
⌘I
Full price-list snapshot (gzipped NDJSON)
curl --request GET \
--url https://csboard.com/v1/prices/snapshot.ndjson.gz \
--header 'Authorization: Bearer <token>'import requests
url = "https://csboard.com/v1/prices/snapshot.ndjson.gz"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://csboard.com/v1/prices/snapshot.ndjson.gz', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://csboard.com/v1/prices/snapshot.ndjson.gz",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://csboard.com/v1/prices/snapshot.ndjson.gz"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://csboard.com/v1/prices/snapshot.ndjson.gz")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://csboard.com/v1/prices/snapshot.ndjson.gz")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body"<string>"{
"code": "missing_api_key",
"detail": "Provide your API key via `Authorization: Bearer csb_pub_…`. Generate one at https://csboard.com/profile?tab=api"
}{
"code": "rate_limit_exceeded",
"detail": "Rate limit of 100 requests/min exceeded."
}