hooks: field of your YAML, and dagraph fires them asynchronously at the right moment. A Slack notification when a run completes, a pager alert when it fails, a log entry when a node starts — all of these are one YAML stanza away.
How hooks work
Hooks are fire-and-forget. They run concurrently with the normal DAG execution flow but never block it. If a hook fails — network error, non-zero exit code, timeout — dagraph logs a warning and moves on. A broken hook endpoint can never fail your DAG.Hook failures are always swallowed. If you need reliable delivery of run events, use a webhook endpoint with its own retry logic, or write to a durable queue in a command hook.
Available events
DAG-level events
DAG-level events
| Event | When it fires |
|---|---|
on_dag_start | Immediately before the first node is dispatched |
on_dag_complete | After all nodes finish successfully |
on_dag_paused | When an approval_gate or user_input node pauses the run |
on_dag_failed | When any node raises an unhandled error or budget is exceeded |
Node-level events
Node-level events
| Event | When it fires |
|---|---|
on_node_start | Immediately before a node begins executing |
on_node_complete | After a node finishes successfully |
on_node_failed | After a node fails (after all retry attempts are exhausted) |
Hook types
Webhook hook
Thewebhook type sends an HTTP POST with a JSON body to the URL you specify. Use it for Slack incoming webhooks, PagerDuty events, custom API endpoints, or any HTTP receiver.
Must be
"webhook".The POST target URL. Supports
${ENV_VAR} substitution — see Environment variable substitution below.A map of header name to value. Values support
${ENV_VAR} substitution. Use this for Authorization headers, Content-Type overrides, or any custom headers your endpoint requires.How long to wait for the HTTP response before giving up. Maximum 60 seconds. Keep this low — a slow webhook should not hold up run completion.
"event" (the event name) plus all available context fields for that event, such as run_id, dag_name, node_id, status, and timing information.
Command hook
Thecommand type runs a shell command. Use it when you need more flexibility than a simple HTTP call — for example, piping run data into a script, appending to a log file, or integrating with tools that have a CLI.
Must be
"command".The shell command to run. Shell expansion is active, so you can use pipes, redirects, and variable substitution via normal shell syntax. The event payload is available two ways: as JSON on stdin, and in the
AGENTGRAPH_EVENT environment variable.How long to wait for the command to exit. Maximum 120 seconds. Stdout and stderr are captured so a verbose command does not pollute the run console.
Environment variable substitution
Webhook URLs and header values support${VAR} syntax for environment variable substitution. This lets you keep secrets out of your YAML files — reference them by environment variable name instead of embedding them directly.
${VAR} substitution — use normal shell variable expansion ($VAR) in the command string instead, since the OS shell handles that.
Complete example
The following example sends a Slack notification on success, triggers a PagerDuty alert on failure, and logs node completions to a local file:Accessing event data in command hooks
The full event payload is available inside a command hook as a JSON string in two places:- stdin — pipe it directly into tools that read from stdin:
jq '.run_id' <<< "$AGENTGRAPH_EVENT" AGENTGRAPH_EVENTenvironment variable — reference it in the command string