API cs.skins

Публичный API отдаёт каталог скинов CS2 с ценами, float и характеристиками, курсы валют, котировку отдельной позиции, оформление заказа и его статус. Публичные методы не требуют ключа: каталог и цены открыты, потому что они и так видны на витрине.

Статус. Сборка демонстрационная: цены вымышленные, реальные платежи не проводятся. Форматы ответов уже такие, какими будут в продакшене, — но значения в них тренировочные. Партнёрский API с ключами (для магазинов и ботов) появится вместе с приёмом платежей; условия ниже отмечены отдельно.

Базовые сведения

Базовый адресhttps://cs-skins.ru
ФорматJSON, application/json; charset=utf-8
МетодыGET, POST
КодировкаUTF-8, ответы не сжимаются на уровне API
Валюта по умолчаниюRUB (российский рубль), суммы — в копейках, целым числом
Аутентификацияпубличные методы — без ключа; методы кабинета — cookie сессии Steam или заголовок Authorization: Bearer <token>

О суммах. Денежные поля всегда отдаются парой: minor — целое число в минорных единицах (копейках), formatted — строка для показа. Считать нужно по minor: строка зависит от локали и может измениться. Дробные числа для денег не используются нигде — так не бывает потерь на округлении.

Публичные методы

GET/health

Проверка живости сервиса. Отвечает без обращения к базе.

curl -s https://cs-skins.ru/health
{ "ok": true, "service": "cs-skins-api" }

GET/api/v1/public/rates

Курсы валют, по которым считаются котировки. Коэффициенты означают «сколько рублей в одной единице валюты», база — рубль.

{
  "base": "RUB",
  "updatedAt": "2026-09-29T00:00:00.000Z",
  "demo": true,
  "rates": { "RUB": 1, "USD": 92.5, "EUR": 100.2, "USDT": 92.8 }
}

GET/api/v1/public/items

Каталог: список позиций с ценой витрины, ценой Steam, скидкой, float и признаком доступности. По умолчанию возвращаются все позиции каталога, включая те, что сейчас недоступны к покупке, — наличие проверяйте по полю eligible или фильтром onlyEligible=1.

Параметры запроса

ПараметрТипОписание
searchстрокаПоиск по названию, оружию и скину без учёта регистра.
categoryсписокКатегории через запятую: rifle, sniper, pistol, smg, knife, gloves, sticker, charm.
exteriorсписокКачество: Factory New, Minimal Wear, Field-Tested, Well-Worn, Battle-Scarred. Значение none — «не окрашен».
floatMinчислоНижняя граница float, 0…1.
floatMaxчислоВерхняя граница float, 0…1.
priceMinчислоМинимальная цена витрины в рублях.
priceMaxчислоМаксимальная цена витрины в рублях.
rarityсписокРанг: Consumer, Industrial, MilSpec, Restricted, Classified, Covert, Contraband, Extraordinary, Exotic, Remarkable, Master, Superior, Exceptional, Distinguished, Rare.
deliveryсписокТип доставки: instant — сразу после оплаты, up-to-12h — до 12 часов.
tradeLockсписокЗадержка обмена в часах: 0, 24, 48, 120, 168, 720. Значение означает «не больше N часов».
statTrakфлаг1 — только StatTrak™, 0 — только без него.
souvenirфлаг1 / 0 — только сувенирные или только обычные.
vanillaфлаг1 / 0 — только без окраса или только окрашенные.
phaseсписокФаза окраса, например Doppler Phase 2.
stickerTypeсписокТипы наклеек: paper, holo, foil, gold, glitter.
stickerCollectionсписокКоллекция наклеек.
stickerCountсписокКоличество наклеек, 0…5. Значение 5 означает «5 и больше».
charmсписокКоллекция брелока.
availabilityстрокаadvance — только позиции, доступные за аванс.
onlyEligibleфлаг1 — только позиции, которые можно купить прямо сейчас.
sortстрокаprice_asc (по умолчанию), price_desc, discount_desc, discount_asc, float_asc, name.

Пример

curl -s "https://cs-skins.ru/api/v1/public/items?category=rifle,knife&floatMax=0.2&sort=price_asc&onlyEligible=1"

Ответ

{
  "currency": "RUB",
  "total": 12,
  "eligibleTotal": 9,
  "items": [ /* массив позиций, описание полей — ниже */ ]
}

Неизвестное значение фильтра трактуется как «фильтр не задан», а не как «ничего не найдено»: опечатка в параметре не должна отдавать пустой каталог. Счётчики для панели фильтров отдаёт /api/v1/public/facets — он принимает те же параметры и возвращает, сколько позиций найдёт каждый пункт при текущем отборе.

GET/api/v1/public/facets

Числа для панели фильтров: сколько позиций останется, если выбрать то или иное значение. Параметры те же, что у списка позиций.

GET/api/v1/public/purchases

Лента состоявшихся покупок для витрины: предмет, цена и время. Необязательный параметр limit (1–24, по умолчанию 10). Данные обезличены — ни идентификатора покупателя, ни трейд-ссылки, ни источника закупки в ответе нет.

curl -s "https://cs-skins.ru/api/v1/public/purchases?limit=10"

GET/api/v1/public/items/{id}

Одна позиция с полной котировкой — то, из чего собирается страница предмета. Идентификатор (id) короткий и читаемый, и берётся он из ответа каталога выше: подставлять сюда чужой пример нельзя, состав витрины меняется вместе с рынком. Человеческий адрес страницы — /item/{id}.

curl -s "https://cs-skins.ru/api/v1/public/items/{id}"

Поля позиции

ПолеТипЧто означает
idстрокаИдентификатор позиции в каталоге.
marketHashNameстрокаПолное имя как в Steam: AK-47 | Fire Serpent (Field-Tested).
weapon, skinстрокаОружие и название окраса по отдельности.
categoryстрокаКатегория: винтовка, нож, перчатки, наклейка, брелок и т. д.
rarity, rarityLabelстрокаРанг и его русская подпись.
exterior, exteriorShort, exteriorLabelстрокаКачество: Field-Tested, FT, «После полевых испытаний».
floatValueчисло или nullТочный «пробег» предмета 0…1. null — у категории float нет (наклейки, брелоки), а не ноль.
statTrak, souvenir, vanillaфлагStatTrak™, сувенирный, без окраса.
collection, phaseстрока или nullКоллекция и фаза окраса (для Doppler и подобных).
stickerCount, stickerTypes, stickerCollectionчисло, список, строкаНаклейки на предмете.
charmCollectionстрока или nullКоллекция брелока.
tradeLockHoursчислоЧерез сколько часов предмет можно передать. 0 — без задержки.
deliveryTierстрокаinstant или up-to-12h.
deliveryстрока или nulldirect — предмет приходит на вашу трейд-ссылку; relay — через наш обменный аккаунт.
advanceAvailableфлагМожно ли взять позицию за аванс.
priceобъектЦена витрины: { minor, formatted }.
steamPriceобъект или nullЦена Steam Market для сравнения; null, если её нет.
steamDiscountBpsчислоСкидка к Steam в базисных пунктах: 1000 = 10 %.
referenceобъектОриентир рынка, от которого считается цена.
volume24hчисло или nullСколько предметов продано за сутки по данным площадки.
eligibleфлагМожно ли купить позицию сейчас. false — кнопка покупки не работает, а причина в rejectReasons.
rejectReasonsсписокТехнические причины отказа: они для отладки, показывать их покупателю нужно человеческим текстом.

Чего в ответе нет и не будет. Цена закупки и площадка, на которой мы берём предмет, наружу не отдаются: это внутренняя экономика сервиса. Ответ содержит только то, что видит покупатель на витрине.

Аккаунт и заказы

Методы ниже требуют, чтобы запрос был от имени пользователя. Есть два способа:

Пользователь определяется только по серверной сессии. Заголовки вроде X-User-Id сервер игнорирует: иначе достаточно было бы подставить чужой идентификатор, чтобы распоряжаться чужим балансом.

GET/api/v1/me

Кто я для сервера и сколько у меня на балансе.

{
  "userId": "demo-user",
  "steamId": "76561198000000000",
  "nick": "unwrong",
  "avatar": "https://avatars.akamai.steamstatic.com/…_full.jpg",
  "avatarSmall": "https://avatars.akamai.steamstatic.com/…_medium.jpg",
  "profileUrl": "https://steamcommunity.com/profiles/76561198000000000",
  "role": "user",
  "balance": { "minor": 3000000, "formatted": "30 000,00 ₽", "availableMinor": 2950000 }
}

availableMinor — сумма, доступная к трате прямо сейчас: из minor уже вычтены зарезервированные под активные заказы деньги. Планировать покупки нужно по ней.

POST/api/v1/orders

Оформить покупку. Цена фиксируется в этот момент: сервер проверяет, что выгода покупателя и потолок закупки сходятся, резервирует деньги на балансе и отправляет закупку площадке с доставкой по вашей трейд-ссылке.

Тело запроса

ПолеТипОписание
itemIdстрокаИдентификатор позиции из каталога. Обязательно.
tradeUrlстрокаВаша трейд-ссылка Steam. Обязательно. Ссылка проверяется до списания.
idempotencyKeyстрокаНеобязательно. Тот же ключ вернёт тот же заказ вместо второй покупки. Можно передать заголовком Idempotency-Key.
curl -s -X POST https://cs-skins.ru/api/v1/orders \
  -H "authorization: Bearer $TOKEN" \
  -H "content-type: application/json" \
  -H "idempotency-key: 6f1c1f6e-0001" \
  -d '{"itemId":"glock-water-elemental-mw","tradeUrl":"https://steamcommunity.com/tradeoffer/new/?partner=1389104827&token=4ypRGYag"}'

Ответ

{
  "id": "9f0f1c1a-…",
  "number": "CS-9F0F1C1A",
  "marketHashName": "Glock-18 | Water Elemental (Minimal Wear)",
  "state": "delivered",
  "price": { "minor": 120000, "formatted": "1 200,00 ₽" },
  "createdAt": "2026-10-01T12:00:00.000Z",
  "updatedAt": "2026-10-01T12:00:04.000Z",
  "needsReview": false,
  "reason": null,
  "rejectReasons": []
}

Статусы заказа

stateКод ответаЧто произошло
delivered201Покупка состоялась, предмет передан по трейд-ссылке. Обмен нужно принять в Steam.
delivering201Закупка отправлена, площадка ещё не подтвердила передачу. Деньги держатся резервом.
rejected409Заказ не принят: не сошлись условия (цена, скидка, оборот). Причины — в rejectReasons. Деньги не списаны.
failed409Закупка не удалась: предмет не передан. Резерв освобождён, деньги остались на балансе.

needsReview: true означает, что покупка прошла, но закрыть заказ автоматически нельзя — им занимается человек. Деньги покупателя в этом случае не освобождаются, пока вопрос не решён.

GET/api/v1/orders

Мои заказы, новые сверху. Формат тот же, что у ответа на оформление.

GET/api/v1/orders/{id}

Один заказ по внутреннему идентификатору. Чужой заказ недоступен: ответ будет 404, а не 403 — так нельзя даже выяснить, существует ли чужой заказ.

POST/api/v1/auth/logout

Завершить текущую сессию: cookie снимается, запись сессии удаляется на сервере.

Поддержка

GET/api/v1/support/status

Доступен ли ИИ-консультант и на какой модели он работает.

{ "available": true, "model": "deepseek/deepseek-v4.1-flash", "detail": null, "checkedAt": "…" }

POST/api/v1/support/chat

Вопрос консультанту. Он отвечает по базе знаний сервиса и не может двигать деньги, менять цены или лимиты. Персональные данные из вопроса вырезаются перед отправкой модели.

ПолеТипОписание
messageстрокаТекст вопроса. Обязательно, непустой.
historyсписокНеобязательно. Прошлые реплики: [{ "role": "user" | "assistant", "content": "…" }].
curl -s -X POST https://cs-skins.ru/api/v1/support/chat \
  -H "content-type: application/json" \
  -d '{"message":"Сколько идёт доставка?","history":[]}'
{ "available": true, "answer": "…", "model": "deepseek/deepseek-v4.1-flash" }

Ограничения и ошибки

ЧтоЛимитОтвет при превышении
Запросы к API с одного адреса120 в минуту429
Оформление заказов одним пользователем20 в минуту429
Сообщения в поддержку с одного адреса12 в минуту429
Размер тела запроса64 КБ413

Ограничитель считает только запросы к /api/: статика витрины под него не попадает, иначе один просмотр каталога съедал бы весь лимит.

Формат ошибки

{ "error": "заказ не найден" }
КодКогда
400Не хватает обязательных полей, сумма или параметр не разобраны.
401Нет действующей сессии. Нужно войти заново.
403Действие доступно другой роли (например, журнал учёта — только администратору).
404Позиции или заказа нет; для чужого заказа — намеренно 404.
409Заказ не прошёл: условия не сошлись. Подробности — в теле ответа.
429Превышен лимит частоты. Стоит подождать и повторить.
503Зависимость недоступна: например, вход через Steam без связи с базой.

Партнёрский API

Отдельный контур для магазинов, ботов и реселлеров: ключ, закреплённый за аккаунтом, покупки без ручного входа и отдельные лимиты. Он ещё не запущен: включать его раньше приёма платежей нельзя.

СтатусВ разработке
ДоступКлюч выдаётся аккаунту, у которого есть оборот. Порог объявим до запуска.
Стоимость доступаОтдельной платы за ключ не будет: доступ входит в обычные условия сервиса.
Что будет доступноКаталог и котировки с текущими ценами, оформление заказа по трейд-ссылке, статус заказа, вебхук о смене статуса, баланс и история операций.
ОграниченияСвой лимит запросов на ключ; покупки — только на своём аккаунте, чужой баланс недоступен.

Платежи ещё не подключены — поэтому ключи пока не выдаются: подписывать ими нечего. Каталог, цены, курсы и характеристики позиций настоящие.

Вопросы

Нужен ли ключ, чтобы читать каталог и цены?

Нет. Каталог, котировки, курсы и характеристики позиций открыты — они и так видны на витрине. Ключ понадобится для партнёрского контура и повышенных лимитов.

Почему суммы в копейках, а не в рублях с дробной частью?

Деньги считаются целыми числами в минорных единицах. Дробные числа с плавающей точкой не используются ни в котировке, ни в журнале, поэтому округление не может создать или отнять копейку.

Почему в ответе нет площадки, откуда берётся предмет?

Это внутренняя экономика сервиса. Покупателю важно, что предмет придёт по его трейд-ссылке за указанную цену, а не где мы его берём. Поле delivery показывает режим передачи, и этого достаточно.

Что происходит с деньгами, если предмет не дошёл?

Резерв освобождается, деньги возвращаются на баланс. Заказ получает статус failed, а если покупка прошла с неясным исходом — needsReview: true и заказ уходит на разбор человеку.

Можно ли отменить заказ через API?

Пока нет: отмена на стороне площадки не поддерживается её же API. Заказ, который застрял, разбирает поддержка, а деньги покупателя при этом остаются зарезервированными, а не списанными.

Нужен доступ или не хватает метода?

Напишите — добавим то, что действительно нужно для интеграции, а не «на всякий случай».

Связаться с нами