Skip to main content
Version: Latest

9.5 Notification Delivery Policies

Controller: NotificationDeliveryPoliciesController · Route: api/v1/NotificationDeliveryPolicies (renamed from the singular NotificationDeliveryPolicyController used in early phase reports — plural is current) · GroupName: notifications · 9 endpoints · Per-channel retry/backoff/dead-letter configuration — see Chapter 12 — Retry Engine for the engine that reads these.

Verb + routePermissionRequestResponse (data)
POST GetDataTableNotificationDeliveryPolicies.ViewAllDtParametersDtResult<NotificationDeliveryPolicyDto> (unwrapped)
GET GetDetails/{id}NotificationDeliveryPolicies.View—NotificationDeliveryPolicyDetailsDto
GET GetEdit/{id}NotificationDeliveryPolicies.Edit—NotificationDeliveryPolicyEditDto
GET GetDropdownList/{findBy}?onlyActive=trueNotificationDeliveryPolicies.Viewroute + queryNotificationDeliveryPolicyViewListDto[]
POST CreateNotificationDeliveryPolicies.CreateNotificationDeliveryPolicyEditDtoGuid
PUT Update/{id}NotificationDeliveryPolicies.EditNotificationDeliveryPolicyEditDtoGuid
DELETE Delete?restore=NotificationDeliveryPolicies.DeleteDeleteDto[]Guid
PUT ActiveNotificationDeliveryPolicies.ActiveDeleteDto[]Guid
PUT DeactiveNotificationDeliveryPolicies.DeactiveDeleteDto[]Guid

Field-level detail — NotificationDeliveryPolicyEditDto​

{
"id": "00000000-0000-0000-0000-000000000000",
"isActive": true,
"displayOrder": 0,
"channel": 1,
"enabled": true,
"maxRetries": 5,
"retryStrategy": 2,
"initialDelaySeconds": 60,
"maximumDelaySeconds": 3600,
"backoffMultiplier": 2.0,
"retryOnTimeout": true,
"retryOnRateLimit": true,
"retryOnNetworkFailure": true,
"retryOnTemporaryFailure": true,
"retryOnPermanentFailure": false,
"deadLetterEnabled": true,
"priority": 5,
"description": "Default Email retry policy",
"fDescription": "Default Email retry policy"
}

retryStrategy: None=0, Fixed=1, ExponentialBackoff=2, Linear=3, Immediate=4.

No FluentValidation validator currently exists for this DTO — invalid combinations (e.g. initialDelaySeconds > maximumDelaySeconds, negative maxRetries) are not rejected server-side today. Treat this as an operational gap when authoring new policies by hand.

Seed defaults (one policy per channel, created by the platform's ApplicationDbSeeder)​

ChannelMaxRetriesStrategyInitialDelayMaxDelay
Email5ExponentialBackoff60s3600s
WhatsApp3ExponentialBackoff30s1800s
SMS3Fixed60s300s
Push5ExponentialBackoff15s900s
SignalR2Linear10s60s
InApp2Fixed5s30s

Business notes: a channel with no delivery policy row falls back to safe engine defaults rather than failing dispatch — but every channel above is seeded on first run, so an explicit policy normally always exists. Retry timing formulas: Fixed = initialDelay; Linear = initialDelay × attemptNumber; Exponential = initialDelay × multiplier^(attempt-1), capped at maximumDelaySeconds; Immediate = 0.

Angular: an admin "delivery tuning" screen — typically one row per channel, rarely created ad hoc since all 6 channels are pre-seeded. Backend: read via the ERP's DeliveryPolicyRepositoryAdapter, which bridges IRepositoryAsync to the framework's IDeliveryPolicyRepository port — see §5.6. Related APIs: Retry Queue, Dead Letters, Chapter 12.