Документация · v1
ПубличныйAPI
Постройте витрину, лендинг или магазин на своём домене, а каталог, остатки и заказы держите в Business Bro.
https://app.businessbro.az/api/public/v1Начало работы
- 01Войдите в консоль и откройте «Настройки → Каналы».
- 02В блоке «Публичный API витрины» нажмите «Включить публичный API» — вы получите ключ pk_…
- 03Впишите домены витрины в «Разрешённые домены» — ключ будет работать только с них.
Аутентификация
Каждый запрос передаёт публичный ключ в заголовке x-public-key. Для ссылок, где заголовок задать нельзя, поддерживается параметр ?key=
pk_ — публичный
Можно положить в JavaScript витрины. Открывает каталог и создание заказа, заявки и записи.
sk_ — секретный
Ключ агента из того же раздела. Даёт доступ к клиентам и расписанию — только с вашего сервера.
curl
curl "https://app.businessbro.az/api/public/v1/products?limit=10" \
-H "x-public-key: pk_…"JavaScript
const api = (path, init = {}) =>
fetch("https://app.businessbro.az/api/public/v1" + path, {
...init,
headers: { "Content-Type": "application/json",
"x-public-key": "pk_…", ...init.headers },
}).then((r) => r.json());
const { products } = await api("/products?inStock=1");/shopПрофиль бизнеса
Название, валюта, часы работы и то, какие разделы доступны: каталог товаров, заказы, запись.
Ответ
{
"shop": {
"name": "Rue",
"currency": "AZN",
"businessType": "instashop",
"businessTypeLabel": "Продажи",
"clientTerm": "Покупатели",
"workingHours": { "open": "09:00", "close": "19:00", "workdays": [1,2,3,4,5,6] },
"features": { "products": true, "orders": true, "booking": true }
}
}/categoriesКатегории
Дерево категорий в два уровня. Скрытые категории наружу не отдаются.
Параметры запроса
kindproducts | servicesЧто запрашиваем. По умолчанию products.
Ответ
{
"categories": [
{
"id": "cat_1",
"name": "Одежда",
"children": [{ "id": "cat_2", "name": "Футболки" }]
}
]
}/productsКаталог товаров
Активные товары с ценами, остатками, фотографиями и вариациями. Остаток товара с вариациями — сумма их остатков.
Параметры запроса
categorystringid категории или её название.qstringПоиск по названию и артикулу.inStock1Только то, что есть в наличии.limitnumberСколько вернуть, максимум 100. По умолчанию 50.offsetnumberСмещение для постраничного вывода.
Ответ
{
"products": [
{
"id": "prd_1",
"name": "Футболка oversize",
"sku": "TSH-001",
"category": "Одежда",
"price": 30,
"currency": "AZN",
"unit": "шт",
"stock": 16,
"inStock": true,
"images": ["https://…/photo.jpg"],
"variants": [
{ "id": "var_1", "name": "M / чёрный", "sku": "TSH-001-M-BK",
"price": 32, "stock": 4, "inStock": true }
]
}
],
"total": 1, "limit": 50, "offset": 0
}/products/{id}Карточка товара
Один товар со всеми фотографиями и вариациями. Отвечает 404, если товар скрыт или не найден.
Ответ
{ "product": { "id": "prd_1", "name": "Футболка oversize", "…": "…" } }/servicesПрайс услуг
Активные услуги с ценой и длительностью. Длительность нужна, чтобы запросить свободные окна.
Параметры запроса
categorystringid направления или его название.qstringПоиск по названию.
Ответ
{
"services": [
{ "id": "srv_1", "name": "Доставка по городу", "price": 5,
"currency": "AZN", "durationMin": 15, "category": "Доставка" }
]
}/ordersОформить заказ
Создаёт заказ в консоли. Сумму считает сервер по ценам из базы — цену из корзины покупателя мы не принимаем. Покупатель ищется по телефону, новый создаётся автоматически.
Тело запроса (JSON)
namestringобязИмя покупателя.phonestringобязТелефон — по нему находится существующий покупатель.itemsarrayобязПозиции: [{ productId, variantId?, qty }]. До 50 штук.addressstringАдрес доставки.notesstringКомментарий к заказу.
Ответ
{
"order": {
"id": "ord_1",
"number": "A31F02",
"status": "NEW",
"total": 64,
"currency": "AZN",
"items": [{ "name": "Футболка oversize · M / чёрный", "qty": 2, "price": 32 }],
"createdAt": "2026-09-06T10:12:03.000Z"
}
}/availabilityСвободные окна
Слоты на дату с учётом рабочих часов, выходных и занятости. Прошедшее время не возвращается.
Параметры запроса
dateYYYY-MM-DDДата. По умолчанию сегодня.serviceIdstringУслуга — из неё берётся длительность.durationMinnumberДлительность вручную, если услуга не выбрана. По умолчанию 30.
Ответ
{
"date": "2026-09-08",
"open": true,
"durationMin": 30,
"slots": [
{ "time": "10:00", "startAt": "2026-09-08T06:00:00.000Z" },
{ "time": "10:30", "startAt": "2026-09-08T06:30:00.000Z" }
]
}/appointmentsЗаписать клиента
Создаёт запись и отправляет клиенту уведомление. Если время занято, возвращает 409 и ближайшее свободное.
Тело запроса (JSON)
namestringобязИмя клиента.phonestringобязТелефон клиента.startAtISO 8601обязВремя начала — значение startAt из /availability.serviceIdstringУслуга: задаёт направление и длительность.notesstringКомментарий.
Ответ
{
"appointment": {
"id": "apt_1",
"startAt": "2026-09-08T06:00:00.000Z",
"durationMin": 30,
"status": "SCHEDULED"
}
}/leadsЗаявка с формы
Отправляет обращение в раздел «Заявки». Подходит для формы обратной связи, когда запись не нужна.
Тело запроса (JSON)
namestringобязИмя.phonestringобязТелефон.servicestringИнтересующее направление.messagestringТекст обращения.
Ответ
{ "lead": { "id": "led_1", "status": "NEW", "createdAt": "2026-09-06T10:12:03.000Z" } }Ошибки
Тело ошибки — { "error": "…", "hint": "…" }
unauthorized401Ключ не передан, неверен или публичный API выключен в консоли.origin_not_allowed403Домен запроса не в списке разрешённых. Добавьте его в «Каналы».not_found404Объект не найден или скрыт от витрины.invalid_request400Не хватает обязательных полей — подсказка в поле hint.product_not_found400Товара из корзины нет в каталоге или он скрыт.variant_not_found400Указанной вариации нет или она скрыта.orders_not_available400У бизнеса выключен приём заказов (не тип «Продажи»).client_limit_reached400Достигнут лимит клиентов по тарифу.time_conflict409Время занято. В поле suggestion — ближайшее свободное.past_date400Время записи в прошлом.
Лимиты и совместимость
- Версия зафиксирована в адресе: ломающие изменения выйдут как /api/public/v2.
- Списки отдаются страницами: не более 100 записей за запрос.
- CORS открыт всем, пока не задан список доменов; после — только им.
- Ключ можно перевыпустить в консоли: старый перестаёт работать сразу.
