GET/health
Проверка живости сервиса. Отвечает без обращения к базе.
curl -s https://cs-skins.ru/health
{ "ok": true, "service": "cs-skins-api" }
Публичный API отдаёт каталог скинов CS2 с ценами, float и характеристиками, курсы валют, котировку отдельной позиции, оформление заказа и его статус. Публичные методы не требуют ключа: каталог и цены открыты, потому что они и так видны на витрине.
| Базовый адрес | https://cs-skins.ru |
| Формат | JSON, application/json; charset=utf-8 |
| Методы | GET, POST |
| Кодировка | UTF-8, ответы не сжимаются на уровне API |
| Валюта по умолчанию | RUB (российский рубль), суммы — в копейках, целым числом |
| Аутентификация | публичные методы — без ключа; методы кабинета — cookie сессии Steam или заголовок Authorization: Bearer <token> |
О суммах. Денежные поля всегда отдаются парой: minor — целое число в минорных единицах (копейках), formatted — строка для показа. Считать нужно по minor: строка зависит от локали и может измениться. Дробные числа для денег не используются нигде — так не бывает потерь на округлении.
Проверка живости сервиса. Отвечает без обращения к базе.
curl -s https://cs-skins.ru/health
{ "ok": true, "service": "cs-skins-api" }
Курсы валют, по которым считаются котировки. Коэффициенты означают «сколько рублей в одной единице валюты», база — рубль.
{
"base": "RUB",
"updatedAt": "2026-09-29T00:00:00.000Z",
"demo": true,
"rates": { "RUB": 1, "USD": 92.5, "EUR": 100.2, "USDT": 92.8 }
}
Каталог: список позиций с ценой витрины, ценой 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 — он принимает те же параметры и возвращает, сколько позиций найдёт каждый пункт при текущем отборе.
Числа для панели фильтров: сколько позиций останется, если выбрать то или иное значение. Параметры те же, что у списка позиций.
Лента состоявшихся покупок для витрины: предмет, цена и время. Необязательный параметр limit (1–24, по умолчанию 10). Данные обезличены — ни идентификатора покупателя, ни трейд-ссылки, ни источника закупки в ответе нет.
curl -s "https://cs-skins.ru/api/v1/public/purchases?limit=10"
Одна позиция с полной котировкой — то, из чего собирается страница предмета. Идентификатор (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 | строка или null | direct — предмет приходит на вашу трейд-ссылку; relay — через наш обменный аккаунт. |
| advanceAvailable | флаг | Можно ли взять позицию за аванс. |
| price | объект | Цена витрины: { minor, formatted }. |
| steamPrice | объект или null | Цена Steam Market для сравнения; null, если её нет. |
| steamDiscountBps | число | Скидка к Steam в базисных пунктах: 1000 = 10 %. |
| reference | объект | Ориентир рынка, от которого считается цена. |
| volume24h | число или null | Сколько предметов продано за сутки по данным площадки. |
| eligible | флаг | Можно ли купить позицию сейчас. false — кнопка покупки не работает, а причина в rejectReasons. |
| rejectReasons | список | Технические причины отказа: они для отладки, показывать их покупателю нужно человеческим текстом. |
Чего в ответе нет и не будет. Цена закупки и площадка, на которой мы берём предмет, наружу не отдаются: это внутренняя экономика сервиса. Ответ содержит только то, что видит покупатель на витрине.
Методы ниже требуют, чтобы запрос был от имени пользователя. Есть два способа:
Кто я для сервера и сколько у меня на балансе.
{
"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 уже вычтены зарезервированные под активные заказы деньги. Планировать покупки нужно по ней.
Оформить покупку. Цена фиксируется в этот момент: сервер проверяет, что выгода покупателя и потолок закупки сходятся, резервирует деньги на балансе и отправляет закупку площадке с доставкой по вашей трейд-ссылке.
Тело запроса
| Поле | Тип | Описание |
|---|---|---|
| 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 | Код ответа | Что произошло |
|---|---|---|
| delivered | 201 | Покупка состоялась, предмет передан по трейд-ссылке. Обмен нужно принять в Steam. |
| delivering | 201 | Закупка отправлена, площадка ещё не подтвердила передачу. Деньги держатся резервом. |
| rejected | 409 | Заказ не принят: не сошлись условия (цена, скидка, оборот). Причины — в rejectReasons. Деньги не списаны. |
| failed | 409 | Закупка не удалась: предмет не передан. Резерв освобождён, деньги остались на балансе. |
needsReview: true означает, что покупка прошла, но закрыть заказ автоматически нельзя — им занимается человек. Деньги покупателя в этом случае не освобождаются, пока вопрос не решён.
Мои заказы, новые сверху. Формат тот же, что у ответа на оформление.
Один заказ по внутреннему идентификатору. Чужой заказ недоступен: ответ будет 404, а не 403 — так нельзя даже выяснить, существует ли чужой заказ.
Завершить текущую сессию: cookie снимается, запись сессии удаляется на сервере.
Доступен ли ИИ-консультант и на какой модели он работает.
{ "available": true, "model": "deepseek/deepseek-v4.1-flash", "detail": null, "checkedAt": "…" }
Вопрос консультанту. Он отвечает по базе знаний сервиса и не может двигать деньги, менять цены или лимиты. Персональные данные из вопроса вырезаются перед отправкой модели.
| Поле | Тип | Описание |
|---|---|---|
| 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 без связи с базой. |
Отдельный контур для магазинов, ботов и реселлеров: ключ, закреплённый за аккаунтом, покупки без ручного входа и отдельные лимиты. Он ещё не запущен: включать его раньше приёма платежей нельзя.
| Статус | В разработке |
| Доступ | Ключ выдаётся аккаунту, у которого есть оборот. Порог объявим до запуска. |
| Стоимость доступа | Отдельной платы за ключ не будет: доступ входит в обычные условия сервиса. |
| Что будет доступно | Каталог и котировки с текущими ценами, оформление заказа по трейд-ссылке, статус заказа, вебхук о смене статуса, баланс и история операций. |
| Ограничения | Свой лимит запросов на ключ; покупки — только на своём аккаунте, чужой баланс недоступен. |
Платежи ещё не подключены — поэтому ключи пока не выдаются: подписывать ими нечего. Каталог, цены, курсы и характеристики позиций настоящие.
Нет. Каталог, котировки, курсы и характеристики позиций открыты — они и так видны на витрине. Ключ понадобится для партнёрского контура и повышенных лимитов.
Деньги считаются целыми числами в минорных единицах. Дробные числа с плавающей точкой не используются ни в котировке, ни в журнале, поэтому округление не может создать или отнять копейку.
Это внутренняя экономика сервиса. Покупателю важно, что предмет придёт по его трейд-ссылке за указанную цену, а не где мы его берём. Поле delivery показывает режим передачи, и этого достаточно.
Резерв освобождается, деньги возвращаются на баланс. Заказ получает статус failed, а если покупка прошла с неясным исходом — needsReview: true и заказ уходит на разбор человеку.
Пока нет: отмена на стороне площадки не поддерживается её же API. Заказ, который застрял, разбирает поддержка, а деньги покупателя при этом остаются зарезервированными, а не списанными.
Напишите — добавим то, что действительно нужно для интеграции, а не «на всякий случай».
Связаться с нами