API Zalut

Для ботов и скриптов управления лотами и заказами. Версия v1.

Создать токен

Авторизация

Токен создаётся в настройках, в разделе «Разработчикам», и показывается один раз. В базе лежит только его sha256-отпечаток, поэтому забытый токен восстановить нельзя — только выпустить новый. Сессии и куки в API не используются.

curl https://zalut.org/api/v1/me \
  -H "Authorization: Bearer bzh_xxxxxxxxxxxx"

Права: read — только чтение, write — ещё и создание лотов, правка лотов, отправка сообщений. Лимит — 600 запросов в минуту с одного IP-адреса: считаются все запросы к /api/v1, в том числе с ошибкой.

Методы

Суммы в ответах — в копейках (balance, deposit, price). При создании и правке лота price передаётся в рублях.

GET/api/v1/me

Профиль, баланс, залог, текущие ставки комиссии и скидка за оборот.

GET/api/v1/games
GET/api/v1/categories

Справочники слагов — их подставляют при создании лота.

GET/api/v1/catalog?q=&game=&limit=&offset=

Поиск по активным лотам площадки. Удобно для мониторинга цен конкурентов.

GET/api/v1/lots?status=active

Свои лоты со статусами, ценами и расписанием автоподнятия. Статусы: moderation, active, paused, sold, removed.

POST/api/v1/lots write
{
  "game": "pubg",
  "category": "accounts",
  "title": "Аккаунт PUBG Mobile | Conqueror",
  "description": "Почта в комплекте",
  "price": 1999,
  "amount": 1,
  "auto_close": true,
  "attrs": {
    "obtain": "full",
    "level": 72,
    "rank": "conqueror",
    "binding": ["email"],
    "mythics": 12,
    "upgrades": 3,
    "cars": 1,
    "metro": 5
  },
  "agree": true
}

Те же правила, что у мастера выставления лота на сайте:

title — 3–140 символов. price — в рублях, от 1 до 1 000 000 000. description — до 5000 символов. amount — остаток, 1–1 000 000 (по умолчанию 1).

auto_close — учёт остатка (по умолчанию true): каждая оплата списывает купленное количество из amount, на нуле лот получает статус sold. false — для услуг без ограничения количества (буст, обучение): остаток не ведётся.

attrs — характеристики лота: объект «ключ → значение». Ключи и значения те же, что у фильтров каталога в этом разделе (в адресе страницы раздела они видны как attr_<ключ>=<значение>), для нескольких значений — массив. obtain — способ передачи. Обязательные характеристики раздела должны быть заполнены, иначе ответ 400 attrs_required.

agree: true — ты принимаешь условия раздела и способа передачи, как галочки в мастере на сайте. Если условия ещё не приняты, а agree не передан — 409 rules_required.

Новый лот сначала проверяет модератор: в ответе {"ok": true, "id": 123, "status": "moderation"}, в каталоге лот появится после одобрения. Если ручная проверка на площадке выключена, лот сразу получает active, а на проверку уходят только подозрительные.

PATCH/api/v1/lots/:id write

Меняет price, amount, title или status (active / paused / removed). Новое название снова уходит на проверку модератору. Лот на проверке можно только удалить (status: "removed"); у лота с автовыдачей остаток = число загруженных позиций, amount не меняется.

GET/api/v1/orders?role=seller&status=paid

Заказы. role=buyer — покупки. Для бота: опрашивай статус paid — это новые оплаченные заказы.

GET/api/v1/orders/:id/messages
POST/api/v1/orders/:id/messages write

Чат по заказу. Тело: {"body": "текст"}, до 4000 символов. Чат открыт с момента оплаты. Текст уходит как есть, без скрытия контактов (как и в чате на сайте).

Пример бота

Ключи, коды и данные аккаунтов не отправляй ботом в чат открытым текстом. Для этого есть встроенная «⚡ Автовыдача» в «Моих лотах»: позиции хранятся зашифрованными и уходят покупателю сразу после оплаты — на страницу сделки и в чат. Бот ниже только отвечает покупателю по новым оплаченным заказам.

const TOKEN = 'bzh_xxxxxxxxxxxx';
const BASE  = 'https://zalut.org/api/v1';
const greeted = new Set();

const api = (path, opts = {}) => fetch(BASE + path, {
  ...opts,
  headers: {
    'Authorization': `Bearer ${TOKEN}`,
    'Content-Type': 'application/json',
    ...opts.headers,
  },
}).then(r => r.json());

setInterval(async () => {
  const orders = await api('/orders?role=seller&status=paid');
  if (!Array.isArray(orders)) return console.error(orders.error, orders.message);
  for (const o of orders) {
    if (greeted.has(o.id)) continue;
    await api(`/orders/${o.id}/messages`, {
      method: 'POST',
      body: JSON.stringify({ body: 'Спасибо за оплату! Заказ принят, скоро передам товар.' }),
    });
    greeted.add(o.id);
    console.log('новый заказ', o.id, o.lot_title);
  }
}, 15000);

Отметку «товар передан» бот не ставит: статус delivered пока выставляется только из интерфейса, чтобы случайный баг скрипта не закрывал сделки сам.

Ошибки

Все ответы — JSON. При ошибке приходит error (машинный код) и обычно message (текст по-русски).

401 no_token / bad_token

Нет заголовка Authorization, либо токен отозван.

403 banned

Аккаунт заблокирован.

403 read_only

Методу нужен scope write, а у токена только чтение.

400 bad_game / bad_category / bad_title / bad_price

Нет такой игры или раздела у этой игры, название не 3–140 символов, цена вне 1 … 1 000 000 000 ₽.

403 game_not_allowed

В этой игре сейчас продавать нельзя.

400 attrs_required

Не заполнены обязательные характеристики раздела; в missing — их названия.

403 obtain_locked

Выбранный способ передачи (attrs.obtain) открыт только продавцам с нужным числом отзывов — выбери другой способ.

409 quiz_required

Ты ещё не прошёл короткий тест по правилам для новых продавцов — он появляется при первом выставлении лота на сайте.

409 rules_required

Условия раздела или способа передачи ещё не приняты; в keys — какие. Повтори запрос с "agree": true.

409 on_moderation / removed / out_of_stock / autodelivery

PATCH: лот на проверке, снят, нет остатка для включения или остаток ведёт автовыдача.

409 chat_locked

Чат по заказу откроется после оплаты.

429 rate_limited

Больше 600 запросов в минуту с одного IP. Подожди столько секунд, сколько в заголовке Retry-After, и сбавь частоту опроса.