Skip to content

Hooks and Webhooks

Rocky fires lifecycle events at key points during pipeline execution. You can attach shell scripts or HTTP webhooks to any event for notifications, gating, auditing, or custom integrations.

Events are organized into five phases:

Event When Use case
pipeline_start Pipeline begins Slack notification, deploy freeze gate
discover_complete Source discovery finishes Log connector/table counts
compile_complete Compilation finishes Validate types before execution
pipeline_complete Pipeline succeeds Success notification, metrics push
pipeline_error Pipeline fails PagerDuty alert, incident creation
Event When Use case
before_materialize Before table copy Audit logging
after_materialize After table copy Publish to data catalog
materialize_error Table copy fails Per-table alerting
Event When Use case
before_model_run Before compiled model runs Feature flag checks
after_model_run After compiled model runs Lineage metadata push
model_error Model execution fails Debug notification
Event When Use case
before_checks Quality checks begin Mute downstream alerts during expected check windows
check_result A quality check completes Per-check threshold alerting
after_checks All checks finish Aggregate summary to dashboards, gating on total pass rate
drift_detected Schema drift found Schema change notification
anomaly_detected Row count anomaly Data quality alert
Event When Use case
state_synced State store synced Backup confirmation
Event When Use case
budget_breach Observed run cost or duration exceeds a limit declared in [budget] Page oncall on overspend; gate downstream runs on on_breach = "error"

Shell hooks execute a command and pipe the event context as JSON to stdin:

[[hook.on_pipeline_complete]]
command = "bash scripts/slack-notify.sh"
timeout_ms = 5000
on_failure = "warn"

The script receives JSON like:

{
"event": "pipeline_complete",
"run_id": "run_20260402",
"pipeline": "raw",
"timestamp": "2026-04-02T14:30:00Z",
"duration_ms": 45200,
"metadata": {
"table_count": 20
}
}
Mode Behavior
abort Stop the pipeline if the hook fails
warn Log a warning and continue (default)
ignore Silently continue

Use abort for gating hooks (deploy freeze, approval gates). Use warn or ignore for notifications.

The command string is passed to sh -c verbatim. The event context is delivered to the script as JSON on stdin (it is not interpolated into the command line), so the runtime values Rocky exposes (run_id, event, etc.) cannot inject shell metacharacters into your command.

Still, never build a hook command by string-formatting untrusted input (a webhook payload, a Fivetran response, a value pulled from a row, anything you don’t fully control). Use only static commands or commands templated from values you control yourself. If you need to react to dynamic input, hand it off through the JSON context to a script you wrote, and let that script decide what to do with quoting / validation.

Webhooks send HTTP requests instead of running shell commands:

[hook.webhooks.on_pipeline_error]
url = "https://hooks.slack.com/services/T.../B.../xxx"
preset = "slack"
secret = "${WEBHOOK_SECRET}"
Preset Service Body format
slack Slack Incoming Webhook Slack Block Kit JSON
pagerduty PagerDuty Events API v2 PD event payload
datadog Datadog Events API DD event JSON
teams Microsoft Teams Webhook Adaptive Card JSON

Presets provide default body templates and headers. Override any field in your config.

When secret is set, Rocky signs the request body with HMAC-SHA256:

X-Rocky-Signature: sha256=<hex-encoded digest>

The receiving service can verify the signature to ensure the request came from Rocky.

Custom body templates use Mustache-style syntax:

body_template = """
{
"text": "Pipeline {{event}}: {{metadata.tables_copied}} tables copied in {{duration_ms}}ms"
}
"""

Supported: {{field}}, {{metadata.key}}, {{#if field}}...{{/if}}.

Validate your hook configuration without running a real pipeline:

Terminal window
# List all configured hooks
rocky hooks list
# Fire a test event
rocky hooks test on_pipeline_start

The test command sends a synthetic event context to verify scripts execute correctly.