diff --git a/API/ROLAC.API/Services/Notifications/NotificationModels.cs b/API/ROLAC.API/Services/Notifications/NotificationModels.cs
new file mode 100644
index 0000000..3e14f3d
--- /dev/null
+++ b/API/ROLAC.API/Services/Notifications/NotificationModels.cs
@@ -0,0 +1,49 @@
+namespace ROLAC.API.Services.Notifications;
+
+/// Canonical channel discriminators stored in NotificationLog.Channel.
+public static class NotificationChannels
+{
+ public const string Email = "email";
+ public const string Line = "line";
+}
+
+/// Canonical target-type discriminators stored in NotificationLog.TargetType.
+public static class NotificationTargetTypes
+{
+ public const string Email = "email";
+ public const string User = "user";
+ public const string Group = "group";
+}
+
+/// Canonical send statuses stored in NotificationLog.Status.
+public static class NotificationStatuses
+{
+ public const string Sent = "sent";
+ public const string Failed = "failed";
+}
+
+/// One failed delivery within a send batch.
+public sealed record NotificationFailure(string Target, string Error);
+
+/// Aggregated outcome of a send call.
+public sealed record NotificationResult(
+ int SentCount, int FailedCount, IReadOnlyList Failures)
+{
+ public static NotificationResult Empty { get; } =
+ new(0, 0, Array.Empty());
+}
+
+/// A file attached to an outbound email.
+public sealed record EmailAttachment(string FileName, string ContentType, byte[] Content);
+
+///
+/// A request to send one email to a set of members (resolved via Member.Email) and/or raw
+/// addresses. The caller supplies the final HTML body — no templating in this phase.
+///
+public sealed record EmailMessage(
+ IReadOnlyList MemberIds,
+ IReadOnlyList Addresses,
+ string Subject,
+ string HtmlBody,
+ IReadOnlyList? Attachments = null,
+ string? SentByUserId = null);