Вебхуки (исходящие)

Отправляйте события FreeMaint в ваши системы в реальном времени

Чтение 4 мин
Распечатать этот раздел

Вебхуки — это «push»-половина интеграций: не ваша система опрашивает FreeMaint, а FreeMaint отправляет POST на ваш URL сразу, как только что-то происходит. Настройка в «Настройки компании > Вебхуки» (/company-settings/webhooks). Доступно с тарифа Starter (100 доставок в день; с Business — без ограничений).

Доступные события

  • work_order.created — создан заказ-наряд
  • work_order.completed — заказ-наряд переведён в «Завершён»
  • work_order.status_changed — заказ-наряд перешёл в любой статус; в полезной нагрузке передаётся new_status. Срабатывает дополнительно к work_order.completed, который не изменился
  • request.created — подана заявка на обслуживание
  • request.status_changed — заявка согласована, отклонена или отменена
  • part.low_stock — запчасть опустилась до точки заказа или ниже
  • part.out_of_stock — запчасть опустилась до нуля
  • part.low_stock_summary — одна ежедневная сводка на компанию с запчастями на точке заказа или ниже, включая те, что ни разу не двигались
  • part.out_of_stock_summary — та же ежедневная сводка для запчастей с нулевым остатком
  • part.consumed — запчасть списана на заказ-наряд или возвращена
  • compliance.chain_divergence — нарушена хеш-цепочка аудита (Enterprise)
  • asset.downtime_started — открыт простой оборудования
  • asset.downtime_ended — простой оборудования закрыт; длительность можно списывать
  • report.daily_summary — завершённые за день работы, раз в сутки в выбранный вами час
  • purchase_order.created — создан заказ на закупку; полезная нагрузка содержит заказ (reference, status, total_cost, currency, expected_date, erp_reference) и его поставщика
  • purchase_order.status_changed — заказ на закупку сменил статус (утверждён, заказан, отменён…); полезная нагрузка содержит previous_status и new_status
  • purchase_order.received — по заказу на закупку принята поставка (отправляется при каждой поставке, включая частичные); полезная нагрузка перечисляет каждую позицию с quantity_ordered, quantity_received (эта поставка), quantity_received_total и quantity_remaining, а также receipt_id, fully_received и closed_short; new_status — PARTIALLY_RECEIVED, пока товар ещё ожидается, и RECEIVED, когда заказ выполнен или закрыт

part.consumed — зеркалирование склада в ERP

Это событие, на которое нужно подписаться, когда другая система (ERP, биллинг, склад, бухгалтерия) должна отражать то, что реально израсходовало обслуживание. Поле quantity со знаком: отрицательное при выдаче запчасти на работу, положительное при возврате — когда её убирают из заказ-наряда. Так сторно в FreeMaint порождает соответствующий возвратный документ на стороне ERP. Поле stock_movement_id не меняется между повторами и переотправками: используйте его как ключ идемпотентности, и одно и то же списание никогда не проведётся дважды. Важно, если обмен идёт в обе стороны: мутация GraphQL adjustStock НЕ порождает это событие. Так задумано — корректировка запасов, которую ваша собственная система записывает в FreeMaint, не должна возвращаться к вам эхом и учитываться дважды. part.consumed возникает только от расхода, зарегистрированного на заказ-наряде внутри FreeMaint. Деталь также содержит custom_reference — ваш собственный код для неё, то есть customReference, заданный через createPart или updatePart, — чтобы система, ведущая каталог, сопоставляла каждую строку без таблицы идентификаторов FreeMaint.

{ "event": "part.consumed", "timestamp": "2026-08-19T21:04:11.000Z", "data": { "part": { "id": 812, "name": "Подшипник 6204", "part_number": "RLM-204", "reference": "PART-812", "custom_reference": "BC-10045", "unit_cost": 12.5, "unit_of_measure": "шт" }, "quantity": -2, "previous_quantity": 48, "new_quantity": 46, "work_order": { "id": 5521, "reference": "WO-2026-0412", "title": "Замена подшипника" }, "asset": { "id": 91, "name": "Сепаратор 2" }, "location": { "id": 7, "name": "Склад завода" }, "user": { "id": 5627, "name": "А. Техник" }, "stock_movement_id": 88213, "occurred_at": "2026-08-19T21:04:11.000Z" } }

Доставка и подпись

Каждая доставка — это POST с телом JSON и заголовком X-FreeMaint-Signature вида t=<секунды unix>,v1=<hex>, где v1 — это HMAC-SHA256 строки «<t>.<сырое тело>» с ключом, равным секрету вашего вебхука. Проверяйте по СЫРОМУ телу, до любого разбора JSON или повторной сериализации. Мы также шлём X-FreeMaint-Event и X-FreeMaint-Delivery-Id. Ответ 2xx означает успешную доставку; сетевые ошибки и 5xx повторяются до 3 раз с экспоненциальной задержкой (примерно 2, 4 и 8 секунд); 4xx считается окончательным отказом и НЕ повторяется.

Повторная отправка доставки

Каждая попытка сохраняется в истории доставок вебхука вместе со статусом и кодом ответа. Любую завершённую доставку можно оттуда отправить повторно: сохранённая полезная нагрузка уходит без изменений, поэтому бизнес-ключи внутри неё (включая stock_movement_id) остаются прежними, и корректно дедуплицирующий приёмник не проведёт операцию дважды. Так восстанавливают то, что было потеряно, пока ваш эндпоинт лежал или ошибочно отклонял запросы.

Фотографии (необязательно)

Если для вебхука включена опция «Включать фотографии» (по умолчанию выключена), объекты "work_order" и "request" содержат массив "photos": до 4 ссылок HTTPS на изображения JPG, PNG, GIF или WebP, сначала самые новые. Каждая ссылка открывает изображение без входа в систему в течение 7 дней, поэтому сохраняйте файл у себя, если он нужен дольше. Повторная отправка передаёт те же ссылки. Другие события и другие вебхуки не меняются. Для "work_order.created" и "request.created" вебхук с опцией «Включать фотографии» отправляется через 90 секунд после события (поле "timestamp" хранит время события), чтобы в него попали фотографии, загруженные сразу после записи.

Требования к URL

  • Только https:// — обычный http отклоняется
  • Только порт 443 или 8443
  • Хост должен быть доступен из интернета — loopback, частные диапазоны и CGNAT отклоняются
  • Никаких учётных данных в URL (https://user:pass@host отклоняется)
  • Системе, существующей только внутри вашей сети, нужен публичный эндпоинт или ретранслятор (n8n, Make, Zapier) перед ней

Лимиты

  • Starter — 100 доставок в день на компанию
  • Business — без ограничений
  • Enterprise — без ограничений
  • Счётчик считает попытки доставки: три вебхука на одно событие расходуют три единицы
  • Суточный счётчик обнуляется в 00:00 UTC

Совет

Проверяйте заголовок X-FreeMaint-Signature в каждом запросе по сырому телу, чтобы поддельный вызов не смог подвинуть остатки в вашей ERP.

Эта страница была полезна?