Skip to content
Docs/Connect services

Notifications and outbound webhooks

Notification channels define where alerts go. Alert rules choose a run event, optionally restrict it to one flow, and send to one or more channels. Use this to notify operators about failures or deliver run status to your application.

On this pageConfigure a channelCreate an alert ruleTest deliveryReceive a generic webhookDelivery behaviorManage and troubleshoot

Supported destinations are Slack incoming webhooks, email, PagerDuty, and a generic HTTP webhook. These are separate from saved integration connectors.

Configure a channel

Channel reads require notifications.read; creation, deletion, rule changes, and tests require notifications.write. Use an authenticated token for these requests.

Shell
curl --fail-with-body "$DAGY_API_URL/channels" \
  -H "Authorization: Bearer $DAGY_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{
    "name":"Development run callback",
    "channel_type":"webhook",
    "config_json":"{\"url\":\"https://example.com/dagy/events\",\"secret\":\"YOUR_SIGNING_SECRET\"}"
  }'

config_json is a JSON-encoded string, not a nested object. When using a programming language, serialize the channel configuration once, then include that string in the request body. The 201 response contains the channel_id; keep it for the alert rule.

channel_typeFields inside config_jsonPrerequisite
slackwebhook_urlAn incoming webhook for the destination Slack channel
webhookurl; optional secret or signing_secretA reachable endpoint accepting JSON POST requests
pagerdutyrouting_keyA PagerDuty Events API integration key
emailfrom_email, to_email; optional region, subjectSender access configured for email delivery in your Dagy environment

For email, to_email may be one address or a list. Email channels are not SMTP connectors; supplying a sender address alone does not provision email delivery. Confirm the sender is available with your administrator.

Channel configuration is returned by channel read operations. Limit notifications.read to people who may access destination URLs and credentials. Do not assume the credential-redaction behavior of saved connectors also applies here.

Create an alert rule

Shell
curl --fail-with-body "$DAGY_API_URL/alert-rules" \
  -H "Authorization: Bearer $DAGY_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{
    "name":"Order processing failed",
    "trigger":"on_failure",
    "flow_name":"process-orders",
    "channel_ids":["YOUR_CHANNEL_ID"]
  }'

The response is 201 with a rule_id. Omit flow_name to match all flows in the workspace. Rules without a destination in channel_ids deliver nothing.

TriggerCurrent behavior
on_failureAutomatic notifications are emitted by supported run completion paths
on_successAutomatic notifications are emitted by supported run completion paths; cancelled runs can also be classified under this trigger
on_retryAccepted rule value; automatic retry notification emission is not implemented
on_sla_breachAccepted rule value; automatic duration/SLA evaluation is not implemented

sla_seconds is accepted as rule configuration but does not activate a running duration monitor. For a production duration alarm or complete coverage across execution modes, monitor the runs API from your observability system and evaluate the condition there. Validate notifications using the execution mode your integration actually uses.

Test delivery

POST /alert-rules/{rule_id}/test sends real notifications using a synthetic test-run ID. It evaluates all rules matching the selected rule's trigger and flow, so more than one rule can send a message. Use a development destination before testing production paging rules.

Shell
curl --fail-with-body -X POST \
  "$DAGY_API_URL/alert-rules/$RULE_ID/test" \
  -H "Authorization: Bearer $DAGY_TOKEN"
JSON
{"dispatched":1,"test":true}

dispatched counts successful sends. A zero result can mean no matching destination, invalid configuration, disabled records, unavailable delivery, or provider rejection. The test result does not include detailed delivery history.

Receive a generic webhook

The destination receives a JSON POST similar to:

JSON
{
  "event":"on_failure",
  "flow_name":"process-orders",
  "message":"Flow run FAILED\nRule: Order processing failed\nFlow: process-orders\nRun: run-example\nOrg: org-example",
  "org_id":"org-example",
  "rule_id":"rule-example",
  "rule_name":"Order processing failed",
  "run_id":"run-example"
}

Headers include Content-Type: application/json and User-Agent: dagy-notifications/1. When the channel has a signing secret, X-Dagy-Signature contains sha256= followed by the hexadecimal HMAC-SHA256 of the exact request body bytes.

Verify the signature before parsing or acting on the payload:

Python
import hashlib
import hmac

def valid_dagy_signature(raw_body: bytes, header: str, secret: str) -> bool:
    digest = hmac.new(secret.encode("utf-8"), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(header, "sha256=" + digest)

Use your web framework's raw-body accessor. Reformatting or reserializing JSON before verification changes the signed bytes. Keep the secret in your application's secret store.

The signature proves possession of the secret; the payload has no delivery ID or signed timestamp. Apply your own replay policy and deduplicate effects, for example using (org_id, rule_id, run_id, event) when only one action per matching run is intended. Retrieve authoritative run status before making a decision that depends on whether a run succeeded or was cancelled.

Delivery behavior

Notifications are best effort. HTTP destinations have a 10-second timeout, failures do not fail the flow, and there is no documented durable retry, replay, or redelivery API. Respond promptly with a successful HTTP status and queue longer processing in your application.

Do not make the notification the sole record of a critical run outcome. Persist the run ID when starting work and reconcile completion through the runs API.

PagerDuty events use event_action: trigger with a deduplication key based on the rule and run. Failure alerts have critical severity; other events use informational severity. Dagy does not send an automatic PagerDuty resolve event.

Manage and troubleshoot

GET /channels and GET /alert-rules return items arrays. Read an individual record with GET /channels/{id} or GET /alert-rules/{id}. Delete either with DELETE; successful deletion returns {"deleted":true}. There is no update operation for channels or rules: create a replacement and remove the old record.

ProblemCheck
Rule test sends nothingConfirm config_json is a JSON string, credentials are valid, and channel IDs belong to this workspace
403 on management requestConfirm the required notification permission
404Confirm the channel/rule ID still exists
Webhook signature failsUse raw body bytes and the exact configured secret
SLA/retry alert never firesThese triggers have no automatic emitter; use external run monitoring
Missed or duplicate alertReconcile run status and make receiver actions idempotent

For events that start a flow, see inbound webhooks and sensors.