CCarFlow Возможности и модули Создать студиюНачать
Модуль «API и вебхуки»

API CarFlow

Свяжите CRM со своим сайтом, 1С, Битрикс24 или отчётами: читайте клиентов, машины, записи и заказ-наряды, создавайте клиентов и записи, получайте события CRM на свой адрес.

Ключ и первый запрос

Ключ создаёт владелец студии: Настройки → API и вебхуки → Создать ключ. Права: «только чтение» или «чтение и запись». Ключ показывается целиком один раз — сохраните его в надёжном месте. Не вставляйте ключ в код страниц сайта: запросы делайте со своего сервера.

Адрес API: https://<адрес CarFlow>/api/v1. Ключ передаётся заголовком Authorization: Bearer cfk_… или X-Api-Key: cfk_….

curl -H "Authorization: Bearer cfk_ваш_ключ" https://carflow.example/api/v1/studio
Не больше 120 запросов в минуту на ключ. Данные — в JSON, даты и время записей — по часовому поясу студии (2026-10-14T09:00), служебные отметки created_at и updated_at — в UTC.

Ответы и ошибки

Успех — коды 200 и 201. Ошибка — JSON вида {"code": "validation", "message": "Проверьте данные клиента", "errors": {"phone": "…"}}.

КодКогда
401Нет ключа, ключ неверный или отозван
402Подписка студии закончилась — доступно только чтение
403Ключ только для чтения, или модуль «API и вебхуки» не подключён
404Нет такого списка или записи
409Время записи уже занято
422Ошибка в данных — подробности в errors
429Слишком много запросов — подождите минуту

Студия

GET/api/v1/studio — название, адрес страницы записи (slug), валюта, филиалы и права ключа.

{"id": "…", "name": "GlossLab", "slug": "glosslab", "currency": "₽",
 "branches": [{"id": "br1", "name": "Центр", "address": "ул. Ленина, 1"}],
 "key": {"name": "Сайт", "scope": "read"}}

Списки и изменения

GET/api/v1/{список}, где список — clients, cars, bookings, orders, services, packages (комплексы), employees (сотрудники — имя, должность, филиал, без ставок), stock и moves (склад и движения, нужен модуль «Склад»), reviews (отзывы, в том числе с карт), tasks (задачи), а с соответствующими модулями — loyalty (операции с бонусами), passes (абонементы и сертификаты), warranties (гарантийные талоны), quotes (сметы), storage (шины на хранении).

ПараметрЧто значит
updated_sinceТолько изменённые с этого момента, ISO 8601: 2026-10-01T00:00:00Z. Удобно для синхронизации: запомните время прошлого запроса.
limitСколько записей за раз, от 1 до 500 (по умолчанию 100)
offsetС какой записи; следующую страницу подсказывает next_offset (null — это последняя)
GET /api/v1/bookings?updated_since=2026-10-01T00:00:00Z&limit=200

{"items": [{"id": "a1b2c3", "clientId": "…", "carId": "…", "start": "2026-10-14T09:00", "dur": 60,
            "status": "planned", "price": 1500, "items": [{"serviceId": "s1", "name": "Мойка", …}],
            "created_at": "2026-10-10T12:00:00Z", "updated_at": "2026-10-10T12:00:00Z"}],
 "next_offset": null}

Фильтры (можно сочетать): status, clientId, carId, empId, branchId — точное совпадение; date_from и date_to — по дате записи, заказа или срока задачи (ГГГГ-ММ-ДД); phone — клиент по номеру в любом формате; q — поиск по имени, госномеру, VIN, названию. С фильтром в ответе есть total.

GET /api/v1/bookings?date_from=2026-10-14&date_to=2026-10-20&status=planned
GET /api/v1/clients?phone=8 916 111-22-33

Поля — те же, что хранит CRM: у клиента name, phone, email, birthday, source; у машины clientId, make, model, plate, vin; у записи start, dur (минуты), status (planned, confirmed, inwork, ready, done, cancelled, noshow), empId, boxId, branchId; у заказ-наряда num, status (inwork, done, cancelled), items, payments. Удалённые записи в список не попадают — о них сообщают вебхуки *.deleted.

Одна запись

GET/api/v1/{список}/{id} — например /api/v1/orders/a1b2c3.

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

POST/api/v1/clients — нужен ключ «чтение и запись». Если клиент с таким телефоном уже есть, второй не создаётся: в ответе он же и "existing": true.

curl -X POST -H "Authorization: Bearer cfk_…" -H "Content-Type: application/json" \
  -d '{"name": "Пётр", "phone": "+7 999 000-11-22", "email": "p@mail.ru", "consent": true, "source": "Сайт"}' \
  https://carflow.example/api/v1/clients

Поля: name и phone — обязательно; email, birthday (ГГГГ-ММ-ДД), note, source, consent — true, если клиент дал согласие на обработку персональных данных у вас.

Свободное время

GET/api/v1/slots/free?branch=br1&date=2026-10-14&items=[{"serviceId":"s1"}] — окна под выбранные услуги с учётом мастеров, боксов и графика, как на странице записи. items — JSON-список услуг: serviceId, при вариантах — variant, при нескольких штуках — qty.

{"slots": [{"t": "09:00", "start": "2026-10-14T09:00"}, {"t": "10:00", "start": "2026-10-14T10:00"}]}

Создать запись

POST/api/v1/bookings — нужен ключ «чтение и запись». Те же проверки, что у онлайн-записи: услуги, свободное время, мастер и бокс подбираются сами, клиент и машина находятся по телефону и госномеру или создаются.

{"name": "Пётр", "phone": "+79990001122", "consent": true,
 "branchId": "br1", "start": "2026-10-14T09:00",
 "items": [{"serviceId": "s1"}, {"serviceId": "s2", "variant": "Седан"}],
 "car": "Kia Rio", "plate": "А123ВС77", "comment": "Позвонить заранее", "promo": "POL10", "source": "Сайт"}
{"ok": true, "booking_id": "…", "client_id": "…", "start": "2026-10-14T09:00", "service": "Мойка, Полировка (Седан)"}

Время заняли — ответ 409, предложите клиенту другое окно из свободного времени.

Изменить клиента и запись

PATCH/api/v1/clients/{id} — name, phone, email, birthday, note, tags (список меток).

PATCH/api/v1/bookings/{id} — status (planned, confirmed, inwork, ready, done, cancelled, noshow), перенос start (проверяется занятость мастера и бокса, иначе 409), note.

{"status": "confirmed", "start": "2026-10-14T10:00"}

Заказ-наряды и оплаты

POST/api/v1/orders — новый заказ-наряд: clientId, carId, bookingId, items (работы: name, price, qty, serviceId, empId), note. Номер назначается сам.

PATCH/api/v1/orders/{id} — status (planned, inwork, done, cancelled), items, note. «done» при неоплаченном остатке становится awaiting — «ждёт оплату», как в CRM.

POST/api/v1/orders/{id}/payments — оплата из вашей кассы, банка или 1С: amount (отрицательная — возврат), method («Карта», «Наличные», «Безнал по счёту»…), date, note, externalId — ваш номер платежа: повтор с тем же номером не задвоит оплату. Заказ, который ждал оплату, закроется сам.

{"amount": 6000, "method": "Безнал по счёту", "externalId": "1c-000123"}

Склад

Нужен модуль «Склад». POST/api/v1/stock — новая позиция: name, unit, qty, cost (себестоимость), price, min (минимальный остаток), sku, cat.

PATCH/api/v1/stock/{id} — цена, себестоимость, минимальный остаток, название.

POST/api/v1/stock/{id}/moves — движение: type = in (приход, можно с новой cost), out (списание) или set (инвентаризация — фактический остаток), qty, note, date. Удобно для поставок от поставщика и синхронизации с 1С или МойСклад.

{"type": "in", "qty": 12, "cost": 1300, "note": "Поставка №45 от поставщика"}

Сообщения клиентам

POST/api/v1/messages — отправить клиенту сообщение через каналы студии: бот Telegram, MAX, ВКонтакте, CHATPUSH (WhatsApp, Telegram по номеру, SMS) — по очереди, до первой доставки, как уведомления CRM. Клиент — clientId или phone (найдём в базе по номеру). До 30 сообщений в минуту на ключ.

{"phone": "+7 916 111-22-33", "text": "Ваш автомобиль готов, ждём вас до 20:00"}

{"ok": true, "status": "Доставлено в Telegram", "client_id": "…", "id": "api-…"}

Сообщение попадает в журнал уведомлений студии. ok: false — ни один канал не дошёл до клиента, причина в status.

Машины, услуги, задачи

POST/api/v1/cars — машина клиента: clientId, make, model, plate, vin, color, year. Такой госномер у клиента уже есть — вернём его ("existing": true). PATCH/api/v1/cars/{id} — те же поля.

POST/api/v1/services — услуга: name, price, dur (минуты), cat, sub, desc. PATCH/api/v1/services/{id} — цена, длительность, название; active: false — снять с продажи, online: false — скрыть со страницы записи.

POST/api/v1/tasks — задача сотруднику, придёт ему уведомлением: title, note, empId, due (2026-10-15 или 2026-10-15T12:00), clientId, orderId. PATCH/api/v1/tasks/{id} — status (open / done) и поля задачи.

Бонусы и оплата по ссылке

GET/api/v1/clients/{id}/bonus — баланс бонусов (с учётом сгорания, как в CRM), до какого процента ими можно платить, последние операции и статистика приглашённых друзей с личной ссылкой клиента.

POST/api/v1/clients/{id}/bonus — начислить (amount больше 0) или списать (меньше 0) бонусы: reason, date, orderId. Списать больше остатка нельзя — ответ 409.

POST/api/v1/orders/{id}/pay-link — ссылка и QR-код на онлайн-оплату заказа через кассу студии: amount (по умолчанию — остаток), provider (yookassa, tbank, sber, modulbank, robokassa, prodamus; по умолчанию — касса онлайн-записи). Оплата сама попадёт в заказ, придёт вебхук order.paid.

{"id": 42, "provider": "tbank", "amount": 1500, "pay_url": "https://…/pay.html#…", "kassa_url": "https://securepay.tinkoff.ru/…", "qr": "https://…/api/pay/qr/….svg"}

Безопасность и OpenAPI

Ключ можно ограничить адресами вашего сервера: «Настройки → API и вебхуки → IP-адреса». Запрос с другого адреса получит 403 ip_forbidden.

Полное описание в формате OpenAPI 3 — /api/v1/openapi.json: импортируйте его в Postman или Insomnia, либо сгенерируйте клиент на своём языке.

Вебхуки: как работают

Владелец добавляет адрес в Настройки → API и вебхуки (до 5 адресов, только https://) и отмечает события. Когда событие случается — неважно, в CRM, на странице записи, в боте или при онлайн-оплате, — CarFlow отправляет на адрес POST с JSON:

{"id": "d1e2…", "event": "order.paid", "created_at": "2026-10-14T10:05:00Z",
 "data": {"id": "o1", "num": 15, "status": "done", "items": […], "payments": […]},
 "payment": {"id": "p1", "amount": 1500, "method": "Карта"}}

Заголовки: X-CarFlow-Event — событие, X-CarFlow-Delivery — id доставки (одна и та же доставка при повторе приходит с тем же id — по нему убирайте дубли), X-CarFlow-Signature — подпись.

Ответьте кодом 2xx в течение 10 секунд. Иначе CarFlow повторит через 1 мин, 5 мин, 30 мин, 2 ч и 6 ч; после этого доставка помечается «не доставлен», и её можно отправить снова из журнала доставок. Перенаправления (3xx) не выполняются.

События

СобытиеКогда
client.created / client.updated / client.deletedНовый клиент, изменение карточки, удаление
booking.createdНовая запись — из CRM, онлайн-записи, бота, API
booking.updatedЗапись изменена: время, услуги, статус
booking.cancelledЗапись отменена (вместе с ней приходит и booking.updated, если выбрано)
booking.deletedЗапись удалена
order.created / order.updated / order.deletedЗаказ-наряд создан, изменён, удалён
order.closedЗаказ закрыт — машина выдана
order.paidНовая оплата в заказе (на месте или онлайн), оплата — в поле payment
stock.created / stock.updatedНовая позиция на складе; изменились остаток, цена или себестоимость
review.createdНовый отзыв: оценка после визита или отзыв с карт
pingКнопка «Проверить» в настройках

Проверка подписи

У каждого адреса свой секрет (whsec_…, виден в настройках). Подпись — HMAC-SHA256 «сырого» тела запроса этим секретом: X-CarFlow-Signature: sha256=<hex>. Сверяйте до разбора JSON.

# Python
import hashlib, hmac
def ok(body: bytes, header: str, secret: str) -> bool:
    good = "sha256=" + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(good, header or "")
// Node.js
const crypto = require("crypto");
const ok = (body, header, secret) =>
  crypto.timingSafeEqual(Buffer.from("sha256=" + crypto.createHmac("sha256", secret).update(body).digest("hex")), Buffer.from(header || ""));
// PHP
$ok = hash_equals('sha256=' . hash_hmac('sha256', file_get_contents('php://input'), $secret), $_SERVER['HTTP_X_CARFLOW_SIGNATURE'] ?? '');