Документация

Исходящие webhook

Уведомляйте ваши внешние системы о событиях betool — неудачное выполнение, низкий баланс, требуется проверка человеком.

Исходящие webhook

Если канал входящих webhook принимает внешние события для обработки, то исходящие webhook делают обратное: они уведомляют ваши системы, когда в betool происходит значимое событие.

Зачем

У вас, вероятно, уже есть:

  • Система оповещений (PagerDuty, Opsgenie, Slack).
  • ITSM-инструмент (Jira, ServiceNow) для управления тикетами.
  • Кастомный дашборд, агрегирующий состояние ваших операций.

Вместо того чтобы заставлять эти системы опрашивать API betool, подпишите их на исходящие webhook: они получают уведомление мгновенно, как только что-то происходит.

Настройка

  1. Администрирование → Исходящие webhook → Новая подписка.
  2. Выберите:
    • Целевой URL — эндпоинт, который будет получать POST-запросы.
    • События для прослушивания — см. список ниже.
    • HMAC-секрет — генерируется автоматически; используйте его на стороне вашего приёмника для проверки подписей.
  3. (Опционально) Фильтры — ограничение выполнениями конкретного pipeline, уровнем серьёзности и т. д.

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

СобытиеКогда срабатывает
execution.failedВыполнение pipeline завершилось неудачей
execution.requires_humanУзел confirmation ожидает проверки
execution.cost_thresholdВыполнение превысило порог стоимости
billing.low_balanceБаланс кредитов опустился ниже заданного порога
billing.out_of_creditsБаланс равен нулю (активны отказы до вызова)
audit.cross_tenant_readВнешний agent прочитал контент этой организации
webhook.delivery_failedПредыдущий исходящий webhook не удался 3 раза

Формат POST

POST /your/endpoint HTTP/1.1
Content-Type: application/json
X-Betool-Event: execution.failed
X-Betool-Signature: sha256=...
X-Betool-Delivery: dlv_01HXYZ...

{
  "event": "execution.failed",
  "delivered_at": "2026-05-24T10:42:13Z",
  "org_id": "org_...",
  "data": {
    "execution_id": "exec_...",
    "pipeline_id": "pip_...",
    "pipeline_name": "support email triage",
    "failed_node": "agent: classifier",
    "error_kind": "llm_timeout",
    "error_message": "Provider responded after 30s timeout"
  }
}

HMAC-подпись

Заголовок X-Betool-Signature содержит sha256=<hmac>, где hmac = HMAC-SHA256(secret, body). Проверяйте его при получении, чтобы убедиться, что запрос действительно исходит от betool:

import hmac, hashlib

def verify(body: bytes, signature: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(
        secret.encode(),
        body,
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

Повторные попытки и идемпотентность

  • Если ваш эндпоинт отвечает 2xx, событие помечается как доставленное.
  • При ответе не-2xx или тайм-ауте betool повторяет попытку с экспоненциальной задержкой (1 мин, 5 мин, 30 мин, 2 ч, 12 ч, 24 ч — максимум 6 попыток).
  • После 6 неудач событие помечается как dead-letter, и генерируется webhook.delivery_failed (для ваших других активных подписок).

Каждый POST несёт уникальный идентификатор X-Betool-Delivery. Если ваш эндпоинт получает одну и ту же доставку дважды (граничный случай сети), обрабатывайте её идемпотентно.

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

  • Требуется HTTPS — подписки на обычный HTTP отклоняются.
  • Ротируемый секрет — вы можете перегенерировать секрет в любой момент; POST-запросы «в полёте», использующие старый секрет, всё ещё будут приниматься до истечения срока (5 мин).
  • Исходные IP — betool публикует свои исходящие IP на status.betool.fr, чтобы вы могли добавить их в allow-list на вашем межсетевом экране.