Ashva API

Каталог, баланс и заказы — то же, что в боте, только для вашего магазина или автовыдачи. Баланс общий с ботом, пополняется там же.

Доступ

Базовый адрес: https://…. Ключ — в боте, раздел «API». Передавайте его в каждом запросе заголовком:

Authorization: Bearer b2b_…

Ключ даёт право покупать с вашего баланса. Утёк — выпустите новый в боте: старый перестанет работать сразу.

Не больше 5 запросов в секунду (короткий всплеск до 20). Сверх этого — ответ 429.

Баланс

GET/v1/me

{"balance_rub": 12450.0, "username": "myshop"}

Каталог

GET/v1/products

Все лоты витрины. Цена и наличие живые: обновляются автоматически каждые 10 минут. Если позиции нет в наличии, price_rub — null, купить её нельзя.

{"products": [{
  "id": "lot12",
  "title": "ChatGPT Plus · 1 месяц",
  "category": "ChatGPT",
  "description": "Готовый аккаунт, выдача сразу после оплаты.",
  "price_rub": 1290.0,
  "in_stock": true,
  "stock": 37,
  "warranty": "30 дней",
  "terms": "",
  "type": "item",
  "requires": [],
  "quantity": {"min": 1, "max": 1, "step": 1}
}]}
ПолеЧто значит
typeitem — обычная позиция, boost — Discord-бусты
requiresчто передать в заказе: email — почта, на которую добавят доступ; guild_invite — ссылка на сервер для бустов
quantityсколько можно взять за один заказ; у бустов количество чётное
termsособые условия лота — считаются частью правил покупки

GET/v1/products/{id}

Один лот в том же виде.

Заказы

POST/v1/orders

Списывает деньги с баланса и сразу оформляет выдачу. Обычно ответ приходит за несколько секунд, иногда до минуты — ставьте таймаут клиента от 90 секунд.

curl -X POST https://…/v1/orders \
  -H "Authorization: Bearer $ASHVA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"product": "lot12", "client_ref": "order-10045"}'
ПолеЧто значит
productid лота из каталога — обязательно
quantityпо умолчанию минимальное из quantity.min
emailесли в requires есть email
guild_inviteдля бустов: discord.gg/код, бессрочное и без лимита входов
client_refваш номер заказа, до 64 знаков. Повтор запроса с тем же client_ref вернёт уже созданный заказ, а не купит второй раз. Можно передать заголовком Idempotency-Key.
max_total_rubнеобязательная максимальная сумма закупки в рублях. Проверяется по цене заказа непосредственно до списания. Если цена выше — 409 price_limit_exceeded, деньги не списываются. Повтор уже созданного заказа возвращает его прежний результат. Смена товара или количества с тем же ключом вызывает 409 idempotency_conflict.

Ответ 201 — заказ:

{
  "id": 318,
  "product": "lot12",
  "title": "ChatGPT Plus · 1 месяц",
  "quantity": 1,
  "unit_price_rub": 1290.0,
  "total_rub": 1290.0,
  "status": "delivered",
  "delivery": "login: …\npassword: …",
  "client_ref": "order-10045",
  "created_at": "2026-09-25T10:14:03+01:00",
  "delivered_at": "2026-09-25T10:14:07+01:00"
}
statusЧто делать
deliveredвыдача в поле delivery
processingдоступ добавляют на почту — опрашивайте GET /v1/orders/{id} раз в минуту
reviewзаказ проверяет оператор, деньги учтены — ответим в течение часа
refundedвыдать не получилось, деньги вернулись на баланс

GET/v1/orders/{id}

Заказ по номеру.

GET/v1/orders/by-ref/{client_ref}

Ваш заказ по ключу повтора; 404, если ещё не создан. Используйте после сетевого таймаута перед повтором POST. При повторе сохраняйте тот же client_ref. Поддержка этих функций объявлена в capabilities ответа /v1/me и /.

GET/v1/orders?limit=20&offset=0

Ваши заказы, новые первыми. limit до 100.

Ошибки

Тело ошибки: {"error": "код", "message": "понятное описание"}.

HTTPerrorКогда
401unauthorizedнет ключа или он устарел
402insufficient_fundsне хватает денег на балансе
403blockedдоступ закрыт
404not_foundнет такого лота или заказа
409out_of_stockпозиции нет в наличии, деньги не списаны
409price_limit_exceededцена выше max_total_rub, деньги не списаны
409idempotency_conflictключ уже использован для другого товара или количества
409unavailableпозиция закончилась в момент выдачи — деньги уже вернулись, заказ в поле order
422bad_*неверное поле запроса: количество, почта, приглашение
429rate_limitedслишком часто