Публичный REST API ROOM позволяет программно читать ваш каталог событий и продавать билеты по СБП с вашего сайта или сервера. Ключи создаются самостоятельно в бэкстейдже. Все ответы — JSON, суммы — в копейках (минорных единицах валюты).
1. Создайте ключ в разделе «API и вебхуки» бэкстейджа. Для боевых (live) ключей нужна верификация. Для тестов используйте sk_test — заказы создаются с mock-оплатой.
2. Сделайте первый запрос — список ваших событий:
curl https://roombackstage.ru/api/public/v1/events \
-H "Authorization: Bearer sk_test_ВАШ_КЛЮЧ"Ключ передаётся в заголовке Authorization: Bearer <ключ>. Существует два типа ключей:
sk_ — секретный, для сервера. Полный доступ (включая список заказов и персональные данные покупателей). Никогда не публикуйте его в браузере.pk_ — публикуемый, для браузера. Работает только с разрешённых доменов (origin-binding) и не отдаёт персональные данные. Подходит для чекаута на лендинге.Каждый ключ привязан к среде: test (mock-оплата, без реального СБП) или live (реальные платежи). Ключ видит и продаёт билеты только на события своего организатора.
https://roombackstage.ru/api/public/v1Версия зафиксирована в пути (/v1). Ломающие изменения выйдут как /v2 — текущая версия продолжит работать.
Ошибки возвращаются со стабильным конвертом и подходящим HTTP-статусом:
{ "error": { "code": "insufficient_scope", "message": "...", "param": "scope" } }401 unauthorized — нет ключа, ключ невалиден/отозван/истёк.403 forbidden / insufficient_scope / origin_not_allowed — ключу не хватает прав или origin не разрешён.404 not_found — событие/заказ не принадлежит вашему ключу (намеренно не различаем «нет» и «чужое»).409 conflict / seat_conflict — место или тариф уже заняты.410 sales_closed — продажи по событию закрыты.422 — недопустимая операция (например, попытка бесплатного билета или не-СБП оплаты).429 rate_limited — превышен лимит. Смотрите заголовок Retry-After.502 payment_provider_error — провайдер оплаты временно недоступен, повторите.Создание заказа (POST /orders) требует заголовок Idempotency-Key (без него — 400). Повтор с тем же ключом вернёт тот же заказ — защита от двойного списания при ретраях сети:
curl https://roombackstage.ru/api/public/v1/orders \
-H "Authorization: Bearer sk_live_ВАШ_КЛЮЧ" \
-H "Idempotency-Key: order-2026-06-19-abc123" \
-H "Content-Type: application/json" \
-d '{ "tier_id": "...", "quantity": 2, "buyer": { "email": "fan@example.ru" } }'По умолчанию: чтение — ~600 запросов/мин на ключ, создание заказов/броней — ~60/мин. При превышении приходит 429 с заголовками Retry-After, X-RateLimit-Remaining, X-RateLimit-Reset.
GET /events — список опубликованных событий (cursor-пагинация).GET /events/{id} — детали события, тарифы, лайнап.GET /events/{id}/tiers — публичные тарифы.GET /events/{id}/seating — схема зала и статус мест.GET /events/{id}/availability — лёгкое наличие (счётчики + ценовой диапазон).POST /orders/preview — предпросмотр цены и сбора без создания заказа.POST /orders — создать заказ TICKET по СБП (вернёт QR + poll_token).GET /orders/{id} — статус заказа (по poll_token или ключу).POST /orders/{id}/check-status — свежая проверка статуса.POST /seat-holds / DELETE /seat-holds — бронь мест для seating-событий.Пример создания заказа из JavaScript:
const res = await fetch("https://roombackstage.ru/api/public/v1/orders", {
method: "POST",
headers: {
"Authorization": "Bearer sk_live_ВАШ_КЛЮЧ",
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
tier_id: "TIER_ID",
quantity: 2,
buyer: { email: "fan@example.ru" },
return_url: "https://ваш-сайт.ru/spasibo", // опционально, только https
}),
})
const order = await res.json()
// order.payment.qr_image / qr_payload — покажите СБП QR покупателю
// order.poll_token — опрашивайте статус GET /orders/{id} с этим токеномВыбор билетов: tier_id (обычный тариф), либо seat_reservation_ids (места после POST /seat-holds), либо standing_items. Опрашивайте GET /orders/{id} с poll_token до status: "paid" — надёжный фолбэк к вебхукам.
Заказы через API оплачиваются только по СБП (рубли). Бесплатные билеты, Telegram Stars и крипта через API недоступны (422). Покупатель платит ровно цену из каталога — комиссию платформы платит организатор из своей выручки.
Ключи test используют mock-оплату: заказ создаётся, но реального СБП QR и списания нет — он сам гаснет через ~15 минут. Идеально для интеграционных тестов.
ROOM может отправлять POST на ваш сервер при изменении статуса заказа. Настройте эндпоинт в разделе «API и вебхуки». Каталог событий (только билеты):
order.paid — заказ оплачен.order.cancelled — заказ отменён/истёк.order.refunded — по заказу прошёл возврат.Тело — подписанный конверт:
{
"id": "clz8a3k9b0001", // cuid, стабилен между ретраями → дедуп
"type": "order.paid",
"api_version": "2026-06-01",
"created_at": "2026-06-19T10:00:00.000Z",
"data": { "order": { "id": "...", "status": "paid", "total_price": 150000, ... } }
}Каждый запрос подписан заголовком ROOM-Signature: t=<ts>,v1=<hex>, где hex = HMAC-SHA256 от строки `${t}.${rawBody}` с вашим секретом whsec_. Всегда проверяйте подпись:
import crypto from "crypto"
function verify(rawBody, header, secret) {
const [tPart, vPart] = header.split(",")
const t = tPart.replace("t=", "")
const v1 = vPart.replace("v1=", "")
const expected = crypto
.createHmac("sha256", secret)
.update(`${t}.${rawBody}`)
.digest("hex")
// сравнение постоянного времени
return crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected))
}Доставка с ретраями (0с / 1м / 5м / 30м / 2ч / 5ч / 10ч / 24ч). После серии неудач эндпоинт автоматически отключается — мы пришлём уведомление. Дедуплицируйте по id конверта (он стабилен между повторами). Отвечайте 2xx для подтверждения; за деталями (включая персональные данные покупателя) обращайтесь к GET /orders/{id} с ключом sk_.