Skip to main content
Notification webhooks are agreement.notification.triggered events. They use the same webhook subscription, signing, delivery, retry, and filtering system as agreement activity webhooks, but they are created by the notification rules attached to an agreement. Use notification webhooks when Shodai should evaluate agreement notification rules while your backend owns the final side effect, such as sending email through your own SES account.

How notification webhooks work

There are two required setup steps:
  1. Create a webhook subscription that includes agreement.notification.triggered.
  2. Deploy an agreement with an agreement-scoped notificationTemplate whose rules use notification.channel: "external_webhook".
A subscription alone does not create notification events. Shodai sends agreement.notification.triggered only after an external_webhook notification rule resolves at least one recipient.

Attach notification rules at deploy

Pass notificationTemplate to deployWithPermit:
After a successful deploy, the External API scopes the template to the authenticated Shodai account, deployed agreement ID, and agreement template ID. It does not replay a deploy transition. The deploy request returns after the transaction receipt is mined, while the returned chain attribution is still provisional. Shodai evaluates __deploy notification rules later, from the canonical deploy transition produced by finalized chain projection. Projection uses the shared finality pin at head - 20, so this notification does not arrive synchronously with the deploy response.

onTransition rules

onTransition rules evaluate when an agreement transition event reaches the notification service.
For onTransition triggers:
  • from, to, and inputs are optional arrays
  • omitted arrays act as wildcards
  • inputs: ["__deploy"] matches the finalized deploy transition when chain projection emits it
  • fromState, toState, and input are available for interpolation
  • the webhook payload includes a transition block

Temporal rules

Temporal rules evaluate while an agreement is in one of the configured states.
Temporal triggers support: checkInterval is accepted and stored on temporal triggers, but current hosted evaluation uses a system-wide temporal sweep. Do not rely on checkInterval as a per-rule schedule or cadence guarantee. Each due temporal evaluation has one firing identity before recipients and channels are resolved. Re-evaluating the same firing does not create another logical notification. Each resolved recipient and channel receives its own notification effect. Temporal notification payloads do not include a transition block.

Recipient resolution

Each notification rule has recipients. Shodai resolves those tokens before emitting notification webhook events. Resolved raw values are converted to email addresses in this order:
  1. participant email matching the wallet address or matching the variable key
  2. companion email variable, such as customerEmail for customerWalletAddress
  3. direct email value, when the raw value itself contains an email address
Literal email strings are not collected when placed directly in recipients. To notify a literal email address, pass it as an observer or as the value of a recipient variable. Resolved email addresses are deduped case-insensitively. Unresolved recipients are skipped and logged.

Content interpolation

subject, title, and body support ${variable} interpolation. For onTransition notifications, interpolation context includes the agreement variables plus:
  • agreementName
  • agreementId
  • fromState
  • toState
  • input
For temporal notifications, interpolation context includes the stored agreement variable snapshot plus:
  • agreementName
  • agreementId
Unknown variables remain in the rendered string as ${variableName}.

Payload shape

An onTransition notification webhook includes notification content and transition context:
A temporal notification webhook omits transition:
One resolved rule-recipient pair produces one agreement.notification.triggered event. That event is delivered as signed POST requests to each active webhook subscription that matches the event type and filters. A delivery’s opaque id remains the same across retries and redeliveries, so receivers can dedupe repeated attempts. Different subscriptions receive distinct delivery IDs.

Filter notification events

Notification webhooks support these filters: Temporal notification payloads do not include transition, so they do not match inputIds, fromStates, or toStates filters.

Handle notification events

Your receiver handles notification webhooks like any other Shodai webhook:
  1. verify the signature with the subscription secret
  2. store and dedupe by event id
  3. return 2xx after durable receipt
  4. perform your final side effect asynchronously
For example, the Shodai Reference App converts vendored notification templates to external_webhook, lets hosted Shodai services evaluate transition and temporal rules, receives agreement.notification.triggered, and sends final email through its own AWS SES configuration.