message.sent.v1
Fired when a message is sent through any channel — email, SMS, push, or in-app.
Event Name
message.sent.v1Schema
| Field | Type | Required | Description |
|---|---|---|---|
eventId | uuid | Yes | Unique event identifier |
occurredAt | datetime | Yes | ISO 8601 timestamp |
brandId | uuid | Yes | Brand that sent the message |
personId | uuid | Yes | Recipient person ID |
channel | enum | Yes | Delivery channel: email, sms, push, in_app |
compositionId | string | Yes | Template composition identifier |
dedupKey | string | Yes | Deduplication key (prevents duplicate sends) |
providerId | string | null | No | Delivery provider identifier (e.g., postmark, resend, twilio) |
subjectOrPreview | string | null | No | Email subject line or push notification preview text |
Example Payload
{
"eventId": "660f9500-f3ac-52e5-b827-557766551111",
"occurredAt": "2026-05-19T15:00:00Z",
"brandId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"personId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"channel": "email",
"compositionId": "tpl_welcome01_v3",
"dedupKey": "lead-captured:b2c3d4e5:welcome:2026-05-19",
"providerId": "postmark",
"subjectOrPreview": "Welcome to Loop Health, Jane!"
}Usage
import { validateEvent } from '@loop/contracts';
const payload = {
eventId: crypto.randomUUID(),
occurredAt: new Date().toISOString(),
brandId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
personId: 'b2c3d4e5-f6a7-8901-bcde-f12345678901',
channel: 'email',
compositionId: 'tpl_welcome01_v3',
dedupKey: `lead-captured:b2c3d4e5:welcome:${new Date().toISOString().slice(0, 10)}`,
providerId: 'postmark',
subjectOrPreview: 'Welcome to Loop Health, Jane!',
};
const result = validateEvent('message.sent.v1', payload);
if (result.success) {
await fetch('https://comms.loop.health/api/events', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`,
},
body: JSON.stringify({
event: 'message.sent.v1',
payload: result.data,
}),
});
} else {
console.error('Validation failed:', result.error.issues);
}