OptionalChangeThe kind of change, when the service reports it.
OptionalClientEcho of CreateSubscriptionParams.ClientState. The consumer MUST verify it (constant-time) against the secret stored alongside the subscription.
OptionalIdentifierWhich mailbox / phone number this concerns, when derivable from the payload.
'message' for a content-change notification, 'lifecycle' for a subscription
lifecycle event (see NormalizedNotification.LifecycleEvent).
OptionalLifecycleFor Kind: 'lifecycle': which lifecycle event occurred.
OptionalMessageThe fully parsed inbound message, present ONLY when the provider's transport delivers
the content inline (see SubscriptionCapabilities.DeliversPayloadInline).
When set, the consumer uses this directly and does NOT need to re-fetch via
BaseCommunicationProvider.GetMessages. undefined for HINT-mode providers
(Graph, Gmail), where the content must be pulled using NormalizedNotification.MessageIDs.
Provider message IDs when the notification carries them (Graph resourceData.id,
Twilio MessageSid). An empty array means "something changed; do a targeted
BaseCommunicationProvider.GetMessages". This is the HINT/pointer path; for
inline-payload providers it may still be populated (e.g. Twilio's MessageSid) so a
consumer CAN re-fetch, but NormalizedNotification.Message is present and
authoritative.
OptionalRawThe raw provider payload for this item, for consumer needs beyond the normalized fields above.
OptionalSubscriptionThe remote subscription ID this notification concerns, when the service includes it (Graph does).
A single normalized notification parsed from an inbound webhook payload.
Two delivery modes: HINT vs. INLINE PAYLOAD
A notification is a HINT by default: it signals that something changed and the consumer re-fetches content through the authenticated pull methods (BaseCommunicationProvider.GetMessages / BaseCommunicationProvider.GetSingleMessage), addressed by NormalizedNotification.MessageIDs. This is the safest mode - a forged notification is harmless (worst case: one extra empty sweep) because the real content only ever comes from an authenticated pull.
Some transports, however, deliver the FULL message inline in the webhook body itself (SendGrid Inbound Parse posts the entire parsed email; Twilio posts the SMS body). For those, re-fetching is wasteful or impossible (SendGrid has no inbound-retrieval API at all). Such providers populate NormalizedNotification.Message with the parsed content, and the consumer uses it directly instead of pulling. A provider signals which mode it uses via SubscriptionCapabilities.DeliversPayloadInline.
This inline-OR-pointer shape mirrors the established MJ duality (
FileOutputRef'sfileData?vsfileId?,ArtifactVersion.ContentMode'Text' vs 'File',MediaOutput'sdata?vsurl?): exactly one of the two carries the content for a given provider.SECURITY NOTE for inline mode: because the payload IS the data path, a provider that sets NormalizedNotification.Message MUST also authenticate the notification (ParseNotificationResult.SignatureValid) - or the consumer must - since a forged inline notification is no longer harmless. Providers whose inbound transport is unsigned (SendGrid Inbound Parse) rely on the consumer's URL secret / network controls; this is documented per-provider.