Pragmatic.Notifications
A unified notification pipeline for .NET: one API to send email, webhook, SMS, push, in-app, and Slack notifications, with channel routing, user preferences, delivery tracking, and background processing.
The Problem
Section titled “The Problem”Every notification use case grows its own ad-hoc delivery code: a fresh SMTP client here, an HTTP webhook there, a Twilio call elsewhere, each with its own setup, error handling, retry, and tracking. Add a channel and every call site must change; enforcing user preferences (muted categories, do-not-disturb) consistently becomes impossible.
await smtpClient.SendMailAsync(new MailMessage("noreply@hotel.com", guestEmail) { /* ... */ });await httpClient.PostAsync("https://hooks.slack.com/...", slackJson);await MessageResource.CreateAsync(to: guestPhone, from: "+1555000", body: "...");The Solution
Section titled “The Solution”Send a notification through one pipeline; channel routing, user preferences, delivery tracking, and background processing are handled for you.
await notifier.SendAsync(new NotificationRequest{ Audience = NotificationAudience.EndUser, Recipient = NotificationRecipient.Direct(guest.Email), Content = new NotificationContent { Subject = "Reservation confirmed", Body = "Your reservation has been confirmed.", }, Category = "transactional",});Configure channels once in the host (app.UseNotifications(n => n.AddSmtp(...))); add a new channel
without touching call sites; user preferences and do-not-disturb are enforced centrally.
Use EnqueueAsync instead of SendAsync to hand the notification to the background worker and return
immediately with a tracking id.
Installation
Section titled “Installation”dotnet add package Pragmatic.Notificationsdotnet add package Pragmatic.Notifications.Webhook # optional: webhook channeldotnet add package Pragmatic.Notifications.Slack # optional: Slack incoming webhooksdotnet add package Pragmatic.Notifications.Sms # optional: SMS via Twiliodotnet add package Pragmatic.Notifications.EFCore # optional: database-backed delivery trackingdotnet add package Pragmatic.Notifications.Testing # test projects: capture what was sentThe SMTP channel ships inside Pragmatic.Notifications itself and delegates to Pragmatic.Email.
Status
Section titled “Status”Functional within 1.0.0-alpha: the pipeline, channel routing, user preferences, delivery tracking, and background delivery. See the roadmap.
Channels provided today: e-mail (SMTP), webhook, Slack and SMS (Twilio). NotificationChannel
also declares Push and InApp; those are extension points, not implementations; selecting one
without registering a provider for it makes the send fail with an explanatory error. Implement
INotificationChannel and register it with AddChannel<T>() to add your own.
Addressing a user id, role or tenant requires a recipient resolver. The built-in resolver only
understands direct addresses (Direct, ToWebhook, phone). Turning NotificationRecipient.User(id)
into an address means telling the library where users live; see
Getting Started.
| Concepts | The pipeline, channels, routing, preferences, delivery tracking | | Getting Started | Send your first notification, configure a channel | | Common Mistakes | The most frequent notification pitfalls | | Troubleshooting | Problem/solution guide |
Requirements
Section titled “Requirements”- .NET 10.0+
License
Section titled “License”Part of the Pragmatic.Design ecosystem. See Licensing. Pragmatic.Notifications is licensed under the PolyForm Small Business 1.0.0 license (free for small businesses; commercial license above the threshold).
