Avan Market Avan Market API

Справочник разработчика

Avan Market API

Об изменениях API пишем в Telegram-группе @avan_market_api — подпишитесь, чтобы узнавать об обновлениях заранее.

Быстрый старт

Покупка скина для вашего клиента — это четыре шага:

  • Получите API-ключ в личном кабинете на avan.market и пополните баланс.
  • Найдите нужный скин через поиск или прайс-лист — вам нужен его id.
  • Отправьте покупку с параметрами трейд-ссылки получателя и своим custom_id.
  • Следите за статусом через WebSockets, пока он не станет конечным.
curl https://api.avan.market/v1/user/balance \
  -H "Authorization: Bearer $AVAN_API_KEY"

curl -X POST https://api.avan.market/v1/market/buy \
  -H "Authorization: Bearer $AVAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "8f3a1d6e-b204-4c59-a6e7-1b9d5c0f7e23",
    "partner": "358881436",
    "token": "l6LFC3R8",
    "max_price": 3.60,
    "custom_id": "order-10457"
  }'

Адрес API

Все методы вызываются относительно одного адреса:

https://api.avan.market/v1/

Формат данных

  • Запросы и ответы — JSON в кодировке UTF-8. Для POST-запросов нужен заголовок Content-Type: application/json.
  • Все цены и суммы указаны в долларах США (USD).
  • Даты приходят в формате ISO 8601 по UTC. Фильтры по времени и поле last_update — UNIX-время в секундах.
  • Массивы в строке запроса передаются повтором параметра: ids[]=a&ids[]=b.
  • В ответах могут появляться новые поля — это не считается изменением версии. Не рассчитывайте на то, что набор полей закрыт.

Игры

В параметрах и ответах игра задаётся её App ID в Steam, в адресе прайс-листа — коротким словом.

ИграApp IDВ адресе прайс-листа
Counter-Strike 2730cs
Dota 2570dota
Rust252490rust
Team Fortress 2440tf

Авторизация

К каждому запросу нужно приложить ваш API-ключ. Он указывается в заголовке Authorization по схеме Bearer:

Authorization: Bearer [API_KEY]
  • Ключ создаётся в личном кабинете на avan.market, в разделе «API Ключ», и показывается один раз — сохраните его сразу.
  • Раздел открывается после того, как вы потратили на маркете от 10 $ суммарно. Эта сумма не является платой за подключение и никуда не списывается.
  • Ключ даёт доступ к вашему балансу. Храните его только на своём сервере и не передавайте в браузер или мобильное приложение.
  • Если ключ попал к посторонним, перевыпустите его в кабинете — старый перестанет работать в течение 30 секунд.

Что вернёт сервер, если ключа нет или он неверный

Статус ответа: 401

{
  "code": "unauthorized",
  "message": "Missing or invalid API key."
}

Лимиты запросов

200 запросов в минуту
Общий лимит на все методы, кроме покупки
500 запросов в минуту
Отдельный лимит для метода покупки (v1/market/buy)

Лимиты считаются на API-ключ, а не на IP-адрес. Счётчики независимы: запросы на покупку не расходуют общий лимит, а остальные методы — лимит покупки.

Счётчик обнуляется через 60 секунд после первого запроса. Когда лимит исчерпан, подождите до минуты и повторите запрос.

Кроме того, один аккаунт может держать не больше 10 запросов покупки, выполняющихся одновременно. Одиннадцатый получит 429 с кодом too_many_concurrent_purchases — повторите его, когда завершится один из предыдущих.

Что вернёт сервер, если лимит превышен

Статус ответа: 429

{
  "code": "rate_limited",
  "message": "Request limit exceeded. Retry in a minute."
}

Ошибки

Успешный ответ приходит со статусом 200 (прайс-лист может ответить 304, см. прайс-листы). Любой другой статус означает ошибку, и в теле ответа будет поле message с описанием.

СтатусКогда возникаетЧто делать
401Ключ не передан, неверен или отозванПроверить заголовок Authorization
403Аккаунт заблокированОбратиться в поддержку
404Метод или объект не найденПроверить адрес и идентификатор
409Запрос корректен, но выполнить его нельзя: скин уже продан, не хватает балансаСмотреть поле code — см. ошибки покупки
422Параметры не прошли проверкуВ errors — сообщения по каждому полю
429Превышен лимит запросовПодождать до минуты и повторить запрос
500, 502, 503, 504Сбой на стороне Avan MarketПовторить позже. Покупку — только после проверки по custom_id, см. советы

Ошибка проверки параметров — 422

{
  "message": "The partner field is required. (and 1 more error)",
  "errors": {
    "partner": [
      "The partner field is required."
    ],
    "token": [
      "The token field is required."
    ]
  }
}

Запрос нельзя выполнить — 409

{
  "code": "skin_unavailable",
  "message": "The skin is already sold or reserved."
}

Поле code — короткое постоянное имя ошибки. Проверяйте в коде именно его: текст в message может меняться.

Пагинация

Длинные списки отдаются частями. В API два вида пагинации — какой из них использует метод, указано в его описании.

По страницам — история покупок

Нужная страница выбирается параметром page в строке запроса. Например, GET /v1/market/history?page=4:

{
  "data": [
    ...
  ],
  "meta": {
    "current_page": 4,
    "last_page": 6,
    "per_page": 200,
    "total": 1150
  }
}

Блок meta описывает выдачу целиком. В примере у аккаунта 1150 покупок, по 200 на страницу, то есть 6 страниц. Номер полученной страницы возвращается в meta.current_page — так легко убедиться, что пришла именно она.

По курсору — поиск скинов

Каталог меняется каждую секунду, поэтому у поиска нет номеров страниц и общего количества. Вместо этого в ответе приходит курсор meta.next_page:

{
  "data": [
    ...
  ],
  "meta": {
    "per_page": 200,
    "next_page": "eyJwIjoiZDJjNWI4ZjEtM2E0Ni00ZTcwLTliMWMtN2U0ZjBhNmQ4YzkyIn0"
  }
}

Чтобы получить следующую часть, передайте это значение в параметре next_page: GET /v1/market/search?game=730&next_page=eyJwIjoi...

  • Когда meta.next_page равен null, выдача закончилась.
  • Курсор работает только с теми же фильтрами, с которыми был получен.
  • Курсор — непрозрачная строка: не разбирайте и не составляйте её сами.

Как проходит покупка

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

ЭтапЧто происходитСтатус
1. Покупка принятаСкин зарезервирован за вами, цена списана с баланса. Покупка проходит проверку на стороне Avan Market"0"
2. Трейд отправленПолучателю в Steam ушёл трейд-оффер, ждём его решения"2"
3а. Скин переданПолучатель принял трейд. Покупка завершена"3"
3б. Передать не удалосьПокупка не прошла проверку либо трейд отклонён, истёк, отменён или не был создан. Деньги возвращаются на баланс, если трейд отклонил не сам получатель"6", "7", "8", "10"

Срок выдачи

Не каждый скин можно передать сразу: на часть предметов действует временное ограничение обмена в Steam. Срок виден заранее в поле delivery предмета: 1 — трейд уходит сразу после проверки покупки, 2 — в течение 12 часов. Пока срок не наступил, покупка остаётся в статусе "0".

Возврат денег

Если покупка завершилась любым конечным статусом, кроме "3", её цена возвращается на баланс. Причина записывается в поле return_reason, а если часть суммы была удержана — в поле return_charged_commission.

return_reasonКогда
trade_declinedПолучатель отклонил трейд
trade_canceledТрейд был отменён: получатель не принял его вовремя либо покупка не прошла проверку
trade_create_failedТрейд не удалось создать: закрытый инвентарь, недействительная ссылка, ограничения Steam
item_unavailableПредмет оказался недоступен для передачи
Исключение — трейд, который отклонил сам получатель. В этом случае удерживается 100% цены: деньги на баланс не возвращаются, а удержанная сумма указана в return_charged_commission.

Что нужно от получателя

Аккаунт и трейд-ссылка получателя заранее не проверяются. Если трейд создать не удалось — например, из-за трейд-бана или закрытого инвентаря, — покупка завершится статусом "10", а деньги вернутся на баланс.

  • Инвентарь Steam открыт, а аккаунт не ограничен в обменах.
  • Трейд-ссылка действующая: после её пересоздания в Steam старый token перестаёт работать.
  • Трейд нужно принять до истечения срока, иначе он будет отменён и покупка завершится статусом "6".

Советы по покупке скинов

  • Новые лоты в реальном времени приходят только событием skin_added в WebSockets. Поиск и витрина сайта отстают на несколько минут, а прайс-лист пересобирается раз в минуту — они подходят для сверки, а не для гонки за свежими лотами.
  • Статусы держите в памяти по событиям из канала покупок. /v1/market/info — запасной путь: после переподключения и в случаях, когда сокет недоступен.
  • Давайте каждой покупке свой custom_id и делайте повтор идемпотентным. Не получили ответ (обрыв, таймаут, 5xx) — запросите /v1/market/info?custom_ids[]=…. Пустой data значит, что покупки нет и запрос можно отправить снова. Если покупка уже есть, повтор ответит duplicate_custom_id и вернёт её в data, второй раз скин не спишется.
  • Ставьте на запрос покупки таймаут не меньше 35 секунд: резерв скина и списание могут занять до 30 секунд.
  • Перед покупкой нескольких скинов сверьте цены методом /v1/market/check-basket, а в самой покупке передавайте max_price — цена может измениться между проверкой и покупкой.
  • При обрыве WebSocket переподключайтесь с растущей паузой (1, 2, 4, 8 секунд, но не больше 30) и после подключения сверяйте статусы незавершённых покупок методом /v1/market/info: сообщения, отправленные во время обрыва, не повторяются.
  • Прайс-лист не нужно скачивать чаще, чем он обновляется, — раз в минуту. Передавайте If-None-Match, чтобы не получать документ заново, если он не менялся.

Каталог и события

JSON-прайс-листы

Прайс-лист — это JSON-документ с полными данными обо всех предметах, которые сейчас выставлены на продажу. У каждой игры свой прайс-лист — выберите нужную.

  • Ответ большой — запрашивайте его со сжатием: заголовок Accept-Encoding: gzip.
  • Прайс-лист пересобирается раз в минуту. Поле last_update показывает, когда он был собран.
  • В ответе есть заголовок ETag. Передайте его значение в заголовке If-None-Match следующего запроса: если прайс-лист с тех пор не пересобирался, придёт пустой ответ 304.
  • Сразу после перезапуска сервиса, пока прайс-лист ещё не собран, метод отвечает 503 — повторите запрос через минуту.
  • Прайс-лист подходит для полной сверки каталога раз в несколько минут. Чтобы узнавать о новых скинах сразу, используйте WebSockets.
GET https://api.avan.market/v1/full-list/cs

Ответ — Counter-Strike 2

{
  "status": "success",
  "last_update": 1773826887,
  "items": [
    {
      "id": "9b2f6c1e-4d7a-4f0b-8a3e-5c1d2e7f9a40",
      "game_id": 730,
      "name": "AWP | Asiimov (Field-Tested)",
      "price": 148.5,
      "delivery": 1,
      "asset_id": "53540956125",
      "class_id": "7993037085",
      "float": "0.2744107246398926",
      "paint_seed": 932,
      "name_tag": null,
      "inspect_link": "steam://run/730//+csgo_econ_action_preview%20B9A9415A72297CB8A1B0992EBB91BF89BD810F72114CBAF916BDDBB6B1B9A9628A842CE72507FCF5801504DBB6B1B9A9029C84A50FF207FCB9B08005DBB6B1B9A9339C841D20A007FC59E06505D13A393939B5C9B17896EAA2",
      "stickers": [
        {
          "slot": 0,
          "name": "Sticker | ZywOo (Foil) | Katowice 2019",
          "wear": 0,
          "image": "https://community.cloudflare.steamstatic.com/economy/image/i0CoZ81Ui0m-9KwlBY1L_18myuGuq1wfhWSaZgMttyVfPaERSR0Wqmu7LAocGJai0ki7VeTHjMGgIXSA7FVwptelsxb0SBrOhI_38i1k6f2nZOo-IvPAX2bHwrtw5rFtSii2zR9-sT7Tn4mvdC7BO1chWZckROZZska4jJS5YAEgste8"
        }
      ]
    }
  ]
}
status string
Статус ответа
last_update integer
Время последнего обновления прайс-листа (UNIX-время)
items array
Предметы на продаже
items[].id string (UUID)
Идентификатор предмета на Avan Market
items[].game_id integer
Игра — её App ID в Steam: 730 — Counter-Strike 2, 570 — Dota 2, 252490 — Rust, 440 — Team Fortress 2
items[].name string
Название предмета
items[].price number
Цена
items[].delivery integer
Срок выдачи: 1 — сразу, 2 — в течение 12 часов
items[].asset_id string
Asset ID предмета в Steam
items[].class_id string
Class ID предмета в Steam
items[].float string | null
Float предмета (CS2)
items[].paint_seed integer | null
Paint seed (CS2)
items[].name_tag string | null
Name Tag предмета
items[].inspect_link string | null
Ссылка для осмотра предмета в игре
items[].stickers array
Наклейки на предмете
items[].stickers[].slot integer
Слот наклейки
items[].stickers[].name string
Название наклейки
items[].stickers[].wear number
Износ наклейки
items[].stickers[].image string
URL изображения наклейки
GET https://api.avan.market/v1/full-list/dota

Ответ — Dota 2

{
  "status": "success",
  "last_update": 1773826887,
  "items": [
    {
      "id": "3e8a1f52-7c94-4b6d-9f20-a1d4c7e85b13",
      "game_id": 570,
      "name": "Dragonclaw Hook",
      "price": 412.3,
      "delivery": 1,
      "asset_id": "29384710562",
      "class_id": "57949762",
      "stickers": [
        {
          "slot": null,
          "name": "Inscribed Towers Destroyed",
          "wear": null,
          "image": "https://cdn.steamstatic.com/apps/570/icons/econ/sockets/gem_stat.30d7935c1f0a1b9e8e28c691c2bd28f7d5f471bc.png"
        }
      ]
    }
  ]
}
status string
Статус ответа
last_update integer
Время последнего обновления прайс-листа (UNIX-время)
items array
Предметы на продаже
items[].id string (UUID)
Идентификатор предмета на Avan Market
items[].game_id integer
Игра — её App ID в Steam: 730 — Counter-Strike 2, 570 — Dota 2, 252490 — Rust, 440 — Team Fortress 2
items[].name string
Название предмета
items[].price number
Цена
items[].delivery integer
Срок выдачи: 1 — сразу, 2 — в течение 12 часов
items[].asset_id string
Asset ID предмета в Steam
items[].class_id string
Class ID предмета в Steam
items[].stickers array
Самоцветы и руны, вставленные в предмет
items[].stickers[].slot integer | null
Слот
items[].stickers[].name string
Название
items[].stickers[].wear number | null
Износ
items[].stickers[].image string
URL изображения
GET https://api.avan.market/v1/full-list/rust

Ответ — Rust

{
  "status": "success",
  "last_update": 1773826887,
  "items": [
    {
      "id": "c47d9a06-2b5e-4e13-b8f7-6d0a3f91e2c5",
      "game_id": 252490,
      "name": "Tempered AK47",
      "price": 38.5,
      "delivery": 1,
      "asset_id": "5193846207",
      "class_id": "2143471514"
    }
  ]
}
status string
Статус ответа
last_update integer
Время последнего обновления прайс-листа (UNIX-время)
items array
Предметы на продаже
items[].id string (UUID)
Идентификатор предмета на Avan Market
items[].game_id integer
Игра — её App ID в Steam: 730 — Counter-Strike 2, 570 — Dota 2, 252490 — Rust, 440 — Team Fortress 2
items[].name string
Название предмета
items[].price number
Цена
items[].delivery integer
Срок выдачи: 1 — сразу, 2 — в течение 12 часов
items[].asset_id string
Asset ID предмета в Steam
items[].class_id string
Class ID предмета в Steam
GET https://api.avan.market/v1/full-list/tf

Ответ — Team Fortress 2

{
  "status": "success",
  "last_update": 1773826887,
  "items": [
    {
      "id": "f15b7e3a-90c2-4a68-8d41-2e6c9b0a7d38",
      "game_id": 440,
      "name": "Mann Co. Supply Crate Key",
      "price": 2.14,
      "delivery": 1,
      "asset_id": "14872039561",
      "class_id": "101785959"
    }
  ]
}
status string
Статус ответа
last_update integer
Время последнего обновления прайс-листа (UNIX-время)
items array
Предметы на продаже
items[].id string (UUID)
Идентификатор предмета на Avan Market
items[].game_id integer
Игра — её App ID в Steam: 730 — Counter-Strike 2, 570 — Dota 2, 252490 — Rust, 440 — Team Fortress 2
items[].name string
Название предмета
items[].price number
Цена
items[].delivery integer
Срок выдачи: 1 — сразу, 2 — в течение 12 часов
items[].asset_id string
Asset ID предмета в Steam
items[].class_id string
Class ID предмета в Steam

WebSockets

Через WebSocket сервер сам сообщает об изменениях — это быстрее опроса методов и не расходует лимит запросов.

Подключение

wss://socket.avan.market/api?token=[TOKEN]
  • Получите токен подключения методом /v1/user/get-ws-token и передайте его в параметре token. Сам API-ключ в WebSocket не передаётся.
  • Обмен идёт сообщениями в формате JSON. Специальная библиотека не нужна — подойдёт любой WebSocket-клиент.
  • Токен действует ограниченное время. Когда срок истекает, сервер закрывает соединение с кодом 4002 — запросите новый токен и подключитесь заново.
  • Одновременно можно держать не больше 10 соединений на аккаунт и не больше 20 подписок на соединение.
  • Раз в 30 секунд сервер проверяет соединение служебным ping — обычные WebSocket-клиенты отвечают на него сами.
const { data } = await fetch("https://api.avan.market/v1/user/get-ws-token", {
  headers: { Authorization: `Bearer ${API_KEY}` },
}).then((response) => response.json());

const socket = new WebSocket(`wss://socket.avan.market/api?token=${data.token}`);

socket.onopen = () => {
  socket.send(JSON.stringify({ action: "subscribe", channel: "catalog" }));
  socket.send(JSON.stringify({ action: "subscribe", channel: `purchases:${data.user_id}` }));
};

socket.onmessage = (event) => {
  const message = JSON.parse(event.data);

  if (message.type === "message") {
    console.log(message.channel, message.data.event, message.data);
  }
};

socket.onclose = (event) => {
  console.log("closed", event.code);
};

Что отправляет клиент

ДействиеСообщение
Подписаться на канал{"action": "subscribe", "channel": "catalog"}
Отписаться от канала{"action": "unsubscribe", "channel": "catalog"}
Проверить соединение{"action": "ping"}

Что отправляет сервер

typeКогда приходитДругие поля
connectedСразу после подключенияuser_id, expires_at
subscribedПодписка оформленаchannel
unsubscribedПодписка снятаchannel
messageСобытие в каналеchannel, data — само событие
pongОтвет на ping—
errorЗапрос клиента не выполненcode, иногда channel

Событие приходит в поле data сообщения с type: "message". В примере выше data сокращён, а в примерах ниже показано его полное содержимое.

{
  "type": "message",
  "channel": "catalog",
  "data": {
    "id": "9b2f6c1e-4d7a-4f0b-8a3e-5c1d2e7f9a40",
    "price": 148.5,
    "event": "skin_price_changed"
  }
}

Ошибки и коды закрытия

ЗначениеЧто означает
forbiddenПодписка на чужой личный канал
unknown_channelТакого канала нет
too_many_subscriptionsБольше 20 подписок на одном соединении
invalid_json, unknown_action, message_too_largeСообщение клиента не разобрано
Код закрытия 4001Токен не передан, неверен или уже истёк
Код закрытия 4002Срок токена истёк во время работы
Код закрытия 4003Больше 10 соединений на аккаунт
Код закрытия 4004Клиент не успевает читать сообщения

Канал каталога

Один канал на все игры — отбирайте нужную по полю game_id. В событии skin_price_changed поле price содержит уже новую цену.

Канал

catalog

События

Что произошло Событие
На маркете появился скин skin_added
Скин снят с продажи skin_deleted
У скина поменялась цена skin_price_changed

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

Сообщение — Counter-Strike 2

{
  "id": "9b2f6c1e-4d7a-4f0b-8a3e-5c1d2e7f9a40",
  "game_id": 730,
  "name": "AWP | Asiimov (Field-Tested)",
  "price": 148.5,
  "delivery": 1,
  "asset_id": "53540956125",
  "class_id": "7993037085",
  "float": "0.2744107246398926",
  "paint_seed": 932,
  "name_tag": null,
  "inspect_link": "steam://run/730//+csgo_econ_action_preview%20B9A9415A72297CB8A1B0992EBB91BF89BD810F72114CBAF916BDDBB6B1B9A9628A842CE72507FCF5801504DBB6B1B9A9029C84A50FF207FCB9B08005DBB6B1B9A9339C841D20A007FC59E06505D13A393939B5C9B17896EAA2",
  "stickers": [
    {
      "slot": 0,
      "name": "Sticker | ZywOo (Foil) | Katowice 2019",
      "wear": 0,
      "image": "https://community.cloudflare.steamstatic.com/economy/image/i0CoZ81Ui0m-9KwlBY1L_18myuGuq1wfhWSaZgMttyVfPaERSR0Wqmu7LAocGJai0ki7VeTHjMGgIXSA7FVwptelsxb0SBrOhI_38i1k6f2nZOo-IvPAX2bHwrtw5rFtSii2zR9-sT7Tn4mvdC7BO1chWZckROZZska4jJS5YAEgste8"
    }
  ],
  "event": "skin_added"
}
id string (UUID)
Идентификатор предмета на Avan Market
game_id integer
Игра — её App ID в Steam: 730 — Counter-Strike 2, 570 — Dota 2, 252490 — Rust, 440 — Team Fortress 2
name string
Название предмета
price number
Цена
delivery integer
Срок выдачи: 1 — сразу, 2 — в течение 12 часов
asset_id string
Asset ID предмета в Steam
class_id string
Class ID предмета в Steam
float string | null
Float предмета (CS2)
paint_seed integer | null
Paint seed (CS2)
name_tag string | null
Name Tag предмета
inspect_link string | null
Ссылка для осмотра предмета в игре
stickers array
Наклейки на предмете
stickers[].slot integer
Слот наклейки
stickers[].name string
Название наклейки
stickers[].wear number
Износ наклейки
stickers[].image string
URL изображения наклейки
event string
Название события: skin_added, skin_deleted или skin_price_changed

Сообщение — Dota 2

{
  "id": "3e8a1f52-7c94-4b6d-9f20-a1d4c7e85b13",
  "game_id": 570,
  "name": "Dragonclaw Hook",
  "price": 412.3,
  "delivery": 1,
  "asset_id": "29384710562",
  "class_id": "57949762",
  "stickers": [
    {
      "slot": null,
      "name": "Inscribed Towers Destroyed",
      "wear": null,
      "image": "https://cdn.steamstatic.com/apps/570/icons/econ/sockets/gem_stat.30d7935c1f0a1b9e8e28c691c2bd28f7d5f471bc.png"
    }
  ],
  "event": "skin_price_changed"
}
id string (UUID)
Идентификатор предмета на Avan Market
game_id integer
Игра — её App ID в Steam: 730 — Counter-Strike 2, 570 — Dota 2, 252490 — Rust, 440 — Team Fortress 2
name string
Название предмета
price number
Цена
delivery integer
Срок выдачи: 1 — сразу, 2 — в течение 12 часов
asset_id string
Asset ID предмета в Steam
class_id string
Class ID предмета в Steam
stickers array
Самоцветы и руны, вставленные в предмет
stickers[].slot integer | null
Слот
stickers[].name string
Название
stickers[].wear number | null
Износ
stickers[].image string
URL изображения
event string
Название события: skin_added, skin_deleted или skin_price_changed

Сообщение — Rust

{
  "id": "c47d9a06-2b5e-4e13-b8f7-6d0a3f91e2c5",
  "game_id": 252490,
  "name": "Tempered AK47",
  "price": 38.5,
  "delivery": 1,
  "asset_id": "5193846207",
  "class_id": "2143471514",
  "event": "skin_deleted"
}
id string (UUID)
Идентификатор предмета на Avan Market
game_id integer
Игра — её App ID в Steam: 730 — Counter-Strike 2, 570 — Dota 2, 252490 — Rust, 440 — Team Fortress 2
name string
Название предмета
price number
Цена
delivery integer
Срок выдачи: 1 — сразу, 2 — в течение 12 часов
asset_id string
Asset ID предмета в Steam
class_id string
Class ID предмета в Steam
event string
Название события: skin_added, skin_deleted или skin_price_changed

Сообщение — Team Fortress 2

{
  "id": "f15b7e3a-90c2-4a68-8d41-2e6c9b0a7d38",
  "game_id": 440,
  "name": "Mann Co. Supply Crate Key",
  "price": 2.14,
  "delivery": 1,
  "asset_id": "14872039561",
  "class_id": "101785959",
  "event": "skin_added"
}
id string (UUID)
Идентификатор предмета на Avan Market
game_id integer
Игра — её App ID в Steam: 730 — Counter-Strike 2, 570 — Dota 2, 252490 — Rust, 440 — Team Fortress 2
name string
Название предмета
price number
Цена
delivery integer
Срок выдачи: 1 — сразу, 2 — в течение 12 часов
asset_id string
Asset ID предмета в Steam
class_id string
Class ID предмета в Steam
event string
Название события: skin_added, skin_deleted или skin_price_changed

Канал ваших покупок

Личный канал: в него приходят изменения только ваших покупок. userId — идентификатор вашего аккаунта, он возвращается вместе с токеном подключения.

Канал

purchases:{userId}

События

Что произошло Событие
У покупки изменился статус или данные трейд-оффера purchase_updated

Сообщение

Сообщение содержит покупку целиком — тот же объект, что возвращает метод /v1/market/info, — и поле event.

{
  "purchase_id": "1f0c7a3e-5b2d-4c8f-9a61-3d7e2b9c4f50",
  "custom_id": "order-10457",
  "created_at": "2026-03-18T09:41:27.000Z",
  "steam_id": "76561198319147164",
  "skin": {
    "id": "8f3a1d6e-b204-4c59-a6e7-1b9d5c0f7e23",
    "name": "AK-47 | Slate (Field-Tested)",
    "price": 3.48,
    "status": "2",
    "steam_trade_offer_id": "6981204573",
    "error": null,
    "return_reason": null,
    "return_charged_commission": null
  },
  "event": "purchase_updated"
}
  • Сообщение всегда описывает текущее состояние покупки, поэтому его достаточно просто сохранить поверх прежнего.
  • Одно и то же состояние может прийти дважды. Покупка в конечном статусе больше не меняется — сообщения по ней после этого можно игнорировать.

Методы API

Баланс

GET https://api.avan.market/v1/user/balance

Возвращает текущий баланс вашего аккаунта. Сумма указана в долларах США (USD).

Ответ

{
  "data": {
    "balance": 1284.37
  }
}
data object
data.balance number
Баланс в долларах США (USD)

Купить скин

POST https://api.avan.market/v1/market/buy

Списывает цену скина с баланса и отправляет его получателю трейд-оффером в Steam. Ответ 200 означает, что покупка создана, — дальше следите за её статусом. Подробнее — в разделе «Как проходит покупка».

Параметры partner и token берутся из трейд-ссылки получателя: https://steamcommunity.com/tradeoffer/new/?partner=358881436&token=l6LFC3R8

Параметры

Передаются в теле запроса в формате JSON.

id string (UUID) обязательный
Идентификатор скина на Avan Market
partner string обязательный
Номер аккаунта получателя — значение после partner= в его трейд-ссылке Steam
token string обязательный
Ключ доступа этой ссылки — значение после token=
max_price number
Верхняя граница цены в USD — страховка от покупки дороже, чем вы рассчитывали. Если скин стоит больше, покупка не состоится и деньги не спишутся. Указывать необязательно
custom_id string
Ваш собственный идентификатор покупки, строка до 64 символов. Должен быть уникальным в пределах вашего аккаунта. Указывать необязательно, но с ним нельзя купить один и тот же скин дважды: повторный запрос с тем же значением вернёт ошибку duplicate_custom_id

Ответ

{
  "data": {
    "purchase_id": "1f0c7a3e-5b2d-4c8f-9a61-3d7e2b9c4f50",
    "custom_id": null,
    "created_at": "2026-03-18T09:41:27.000Z",
    "steam_id": "76561198319147164",
    "skin": {
      "id": "8f3a1d6e-b204-4c59-a6e7-1b9d5c0f7e23",
      "name": "AK-47 | Slate (Field-Tested)",
      "price": 3.48,
      "status": "0",
      "steam_trade_offer_id": null,
      "error": null,
      "return_reason": null,
      "return_charged_commission": null
    }
  }
}
data object
Информация о покупке
data.purchase_id string (UUID)
ID покупки
data.custom_id string | null
ID из вашей системы, переданный при покупке
data.created_at string
Дата и время создания покупки (ISO 8601)
data.steam_id string
Steam ID получателя
data.skin object
Купленный скин
data.skin.id string (UUID)
ID предмета на Avan Market
data.skin.name string
Название предмета
data.skin.price number
Цена покупки
data.skin.status string
Код статуса покупки — см. значения поля status
data.skin.steam_trade_offer_id string | null
ID трейд-оффера в Steam
data.skin.error string | null
Ошибка
data.skin.return_reason string | null
Причина возврата, например trade_canceled
data.skin.return_charged_commission number | null
Комиссия, удержанная при возврате
{
  "message": "The partner field is required. (and 1 more error)",
  "errors": {
    "partner": [
      "The partner field is required."
    ],
    "token": [
      "The token field is required."
    ]
  }
}
message string
Общее описание ошибки
errors object
Ошибки валидации, сгруппированные по полям запроса
errors.{поле} string[]
Список сообщений об ошибках для конкретного поля

Ошибки покупки

Если покупка не создана, деньги не списываются. Причину показывает поле code.

СтатусcodeКогда возникаетМожно ли повторить
409skin_unavailableСкин уже продан или зарезервирован другим покупателемНет
409price_exceededЦена скина выше max_priceДа, с новым max_price
409insufficient_balanceНа балансе не хватает денегДа, после пополнения
409duplicate_custom_idЭтот custom_id уже занят прошлой покупкой. Она возвращается в поле dataНе нужно — покупка уже создана
422invalid_trade_linkИз partner и token не получается рабочая трейд-ссылкаДа, с верной ссылкой
403account_blockedВаш аккаунт заблокированНет, обратитесь в поддержку
500–504—Сбой на стороне Avan Market или Steam, результат неизвестенТолько после проверки по custom_id

Найти скины

GET https://api.avan.market/v1/market/search

Возвращает скины, которые прямо сейчас можно купить, — до 200 за один ответ. Следующая часть выдачи запрашивается по курсору.

Выдача поиска отстаёт от реального состояния маркета на несколько минут — так же, как сайт (avan.market/market). Если новые скины нужно видеть сразу, подписывайтесь на WebSockets.

Параметры

game integer обязательный
Игра, по которой идёт поиск, — её App ID в Steam Возможные значения: 730 — Counter-Strike 2, 570 — Dota 2, 252490 — Rust, 440 — Team Fortress 2
float_from number
Нижняя граница float, только для CS2
float_to number
Верхняя граница float, только для CS2
names[] array
Точные названия предметов. Каждое должно целиком совпадать с полем name, вместе с качеством: AWP | Asiimov (Field-Tested). Не больше 100 за один запрос
price_from number
Нижняя граница цены
price_to number
Верхняя граница цены
next_page string
Курсор следующей страницы — значение meta.next_page из предыдущего ответа

Ответ

{
  "data": [
    {
      "id": "d2c5b8f1-3a46-4e70-9b1c-7e4f0a6d8c92",
      "game_id": 730,
      "name": "Glock-18 | Vogue (Field-Tested)",
      "price": 1.86,
      "delivery": 1,
      "asset_id": "40217735519",
      "class_id": "5114539218",
      "float": "0.3127450406551361",
      "paint_seed": null,
      "name_tag": null,
      "inspect_link": null,
      "stickers": [
        {
          "slot": 0,
          "name": "Sticker | ZywOo (Foil) | Katowice 2019",
          "wear": 0,
          "image": "https://community.cloudflare.steamstatic.com/economy/image/i0CoZ81Ui0m-9KwlBY1L_18myuGuq1wfhWSaZgMttyVfPaERSR0Wqmu7LAocGJai0ki7VeTHjMGgIXSA7FVwptelsxb0SBrOhI_38i1k6f2nZOo-IvPAX2bHwrtw5rFtSii2zR9-sT7Tn4mvdC7BO1chWZckROZZska4jJS5YAEgste8"
        }
      ]
    }
  ],
  "meta": {
    "per_page": 200,
    "next_page": "eyJwIjoiZDJjNWI4ZjEtM2E0Ni00ZTcwLTliMWMtN2U0ZjBhNmQ4YzkyIn0"
  }
}
data array
Найденные скины
data[].id string (UUID)
ID предмета на Avan Market
data[].game_id integer
Игра — её App ID в Steam, см. таблицу игр
data[].name string
Название предмета
data[].price number
Цена
data[].delivery integer
Срок выдачи: 1 — сразу, 2 — в течение 12 часов
data[].asset_id string
Asset ID предмета в Steam
data[].class_id string
Class ID предмета в Steam
data[].float string | null
Float предмета (CS2)
data[].paint_seed integer | null
Paint seed (CS2)
data[].name_tag string | null
Name Tag предмета
data[].inspect_link string | null
Ссылка для осмотра предмета в игре (CS2)
data[].stickers array
Наклейки на предмете
data[].stickers[].slot integer
Слот наклейки
data[].stickers[].name string
Название наклейки
data[].stickers[].wear number
Износ наклейки
data[].stickers[].image string
URL изображения наклейки
meta object
Информация о пагинации
meta.per_page integer
Количество элементов на странице
meta.next_page string | null
Курсор следующей страницы — передаётся в параметре next_page. null, если выдача закончилась
{
  "message": "The selected game is invalid.",
  "errors": {
    "game": [
      "The selected game is invalid."
    ]
  }
}
message string
Общее описание ошибки
errors object
Ошибки валидации, сгруппированные по полям запроса
errors.{поле} string[]
Список сообщений об ошибках для конкретного поля

Статусы купленных скинов

GET https://api.avan.market/v1/market/info

Показывает, что сейчас происходит с купленными скинами: возвращает текущий статус каждой покупки.

  • Нужно передать хотя бы один из двух параметров.
  • Покупки, которые не найдены, в ответ не попадают — ошибки при этом не будет. Так можно проверить, создалась ли покупка с вашим custom_id.
  • Для постоянного наблюдения за статусами используйте WebSockets, а этот метод — для сверки после обрыва соединения.

Параметры

custom_ids[] array
Ваши custom_id, указанные при покупке. Не больше 200 за один запрос
purchase_ids[] array
Значения purchase_id из ответов на покупку, в формате UUID. Не больше 200 за один запрос

Ответ

{
  "data": [
    {
      "purchase_id": "1f0c7a3e-5b2d-4c8f-9a61-3d7e2b9c4f50",
      "custom_id": null,
      "created_at": "2026-03-18T09:41:27.000Z",
      "steam_id": "76561198319147164",
      "skin": {
        "id": "8f3a1d6e-b204-4c59-a6e7-1b9d5c0f7e23",
        "name": "AK-47 | Slate (Field-Tested)",
        "price": 3.48,
        "status": "6",
        "steam_trade_offer_id": "6981204573",
        "error": null,
        "return_reason": "trade_canceled",
        "return_charged_commission": null
      }
    }
  ]
}
data array
Покупки
data[].purchase_id string (UUID)
ID покупки
data[].custom_id string | null
ID из вашей системы, переданный при покупке
data[].created_at string
Дата и время создания покупки (ISO 8601)
data[].steam_id string
Steam ID получателя
data[].skin object
Купленный скин
data[].skin.id string (UUID)
ID предмета на Avan Market
data[].skin.name string
Название предмета
data[].skin.price number
Цена покупки
data[].skin.status string
Код статуса покупки — см. значения поля status
data[].skin.steam_trade_offer_id string | null
ID трейд-оффера в Steam
data[].skin.error string | null
Ошибка
data[].skin.return_reason string | null
Причина возврата, например trade_canceled
data[].skin.return_charged_commission number | null
Комиссия, удержанная при возврате
{
  "message": "The purchase ids field must not have more than 200 items.",
  "errors": {
    "purchase_ids": [
      "The purchase ids field must not have more than 200 items."
    ]
  }
}
message string
Общее описание ошибки
errors object
Ошибки валидации, сгруппированные по полям запроса
errors.{поле} string[]
Список сообщений об ошибках для конкретного поля

Значения поля status

Статус покупки приходит строкой с числовым кодом. Покупка в конечном статусе больше не меняется: следить за ней дальше не нужно.

Код Название Что означает Конечный
"0" Processing Покупка обрабатывается, трейд ещё не отправлен Нет
"2" Active Трейд отправлен и ждёт, пока получатель его примет Нет
"3" Accepted Трейд принят, скин передан Да
"6" Canceled Трейд отменён либо покупка не прошла проверку Да
"7" Declined Получатель отклонил трейд Да
"8" InvalidItems Предмет оказался недоступен для передачи Да
"10" CreateFailed Не удалось создать трейд Да

История покупок

GET https://api.avan.market/v1/market/history

Возвращает все покупки вашего аккаунта, от новых к старым, — по 200 на страницу. Пагинация — по страницам.

Параметры

page integer
Какую страницу вернуть, начиная с 1
start_unix_time integer
С какого момента показывать покупки (по времени создания, включительно), UNIX-время в секундах
end_unix_time integer
По какой момент показывать покупки (по времени создания, включительно), UNIX-время в секундах

Ответ

{
  "data": [
    {
      "purchase_id": "1f0c7a3e-5b2d-4c8f-9a61-3d7e2b9c4f50",
      "custom_id": null,
      "created_at": "2026-03-18T09:41:27.000Z",
      "steam_id": "76561198319147164",
      "skin": {
        "id": "8f3a1d6e-b204-4c59-a6e7-1b9d5c0f7e23",
        "name": "AK-47 | Slate (Field-Tested)",
        "price": 3.48,
        "status": "6",
        "steam_trade_offer_id": "6981204573",
        "error": null,
        "return_reason": "trade_canceled",
        "return_charged_commission": null
      }
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 6,
    "per_page": 200,
    "total": 1150
  }
}
data array
Покупки
data[].purchase_id string (UUID)
ID покупки
data[].custom_id string | null
ID из вашей системы, переданный при покупке
data[].created_at string
Дата и время создания покупки (ISO 8601)
data[].steam_id string
Steam ID получателя
data[].skin object
Купленный скин
data[].skin.id string (UUID)
ID предмета на Avan Market
data[].skin.name string
Название предмета
data[].skin.price number
Цена покупки
data[].skin.status string
Код статуса покупки — см. значения поля status
data[].skin.steam_trade_offer_id string | null
ID трейд-оффера в Steam
data[].skin.error string | null
Ошибка
data[].skin.return_reason string | null
Причина возврата, например trade_canceled
data[].skin.return_charged_commission number | null
Комиссия, удержанная при возврате
meta object
Информация о пагинации
meta.current_page integer
Текущая страница
meta.last_page integer
Последняя страница
meta.per_page integer
Количество элементов на странице
meta.total integer
Общее количество элементов
{
  "message": "The start unix time field must be an integer.",
  "errors": {
    "start_unix_time": [
      "The start unix time field must be an integer."
    ]
  }
}
message string
Общее описание ошибки
errors object
Ошибки валидации, сгруппированные по полям запроса
errors.{поле} string[]
Список сообщений об ошибках для конкретного поля

Проверка наличия перед покупкой

GET https://api.avan.market/v1/market/check-basket

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

Параметры

ids[] array обязательный
Идентификаторы скинов, которые нужно проверить. Не больше 100 за один запрос

Ответ

{
  "data": {
    "available_skins": {
      "41c7e9a2-6f58-4d03-b1a4-9e2c8d5f0b76": 0.37,
      "8f3a1d6e-b204-4c59-a6e7-1b9d5c0f7e23": 3.48
    },
    "unavailable_skin_ids": []
  }
}
data object
data.available_skins object
Доступные для покупки скины: ключ — ID скина, значение — цена
data.available_skins.{id} number
Цена скина
data.unavailable_skin_ids string[] (UUID)
ID скинов, недоступных для покупки: проданы, зарезервированы или не существуют
{
  "message": "The ids field is required.",
  "errors": {
    "ids": [
      "The ids field is required."
    ]
  }
}
message string
Общее описание ошибки
errors object
Ошибки валидации, сгруппированные по полям запроса
errors.{поле} string[]
Список сообщений об ошибках для конкретного поля

Токен для WebSockets

GET https://api.avan.market/v1/user/get-ws-token

Возвращает временный токен для подключения к WebSockets. Запрашивайте новый токен при каждом подключении и когда истекает срок прежнего.

Ответ

{
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0ODIxMyIsImV4cCI6MTc3MzgzMDQ4N30.Vx3kQ9mT2rLp8sNa6fWcY1hJ4bZoEu7dG0iKqRyM5tC",
    "user_id": 48213,
    "expires_at": 1773830487
  }
}
data.token string
Токен подключения
data.user_id integer
Идентификатор вашего аккаунта — подставляется в имя личного канала purchases:{userId}
data.expires_at integer
До какого момента токен действует, UNIX-время в секундах