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
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'] ?? '');