Eventlayer / Build a flow
Send registration and ticket emails
Trigger confirmations, schedule reminders, and follow up after check-in using your email service.
What you will build
Keep email delivery in your own provider. Eventlayer supplies ticket activity; your backend selects recipients, renders templates, and schedules messages. Reminders are scheduled by your application, not by an Eventlayer timer webhook.
- 01Ticket activity
- 02Durable email job
- 03Your provider
- 04Guest inbox
Prerequisites
- A configured sender in your email provider and server-side credentials.
- A protected ticket page from the registration guide.
- A durable queue, scheduler, and a verified Eventlayer webhook receiver.
1. Choose the triggers
| Message | Trigger | Check before sending |
|---|---|---|
| Confirmation | ticket.created with an attendee, or ticket.assigned | Current ticket is assigned; confirmation not already sent |
| Reminder | Your scheduler, relative to event start | Ticket still valid, schedule current, recipient still assigned |
| Follow-up | ticket.checked_in | Correct recipient and appropriate communication preferences |
| Cancellation notice | Your revocation workflow or ticket.deleted | Use your saved booking/contact record |
Creating an assigned ticket emits ticket.created; do not subscribe only to
ticket.assigned. If your registration endpoint already enqueues confirmations,
choose it or the webhook as the owner of that job, not both without deduplication.
2. Connect webhooks to a durable inbox
Follow Connect your CRM, steps 2–3 to register the relevant event types and verify signatures. The same receiver can dispatch jobs to both CRM and email workers.
Deduplicate delivery IDs at ingestion, then use a business key for each message, such as ticket ID + attendee ID + message kind. A replay has a new delivery ID, so delivery deduplication alone will not prevent a second email. Include the attendee ID so a reassignment can be handled deliberately.
3. Resolve the recipient and prepare the message
This SDK helper returns an email draft; it does not call an email provider. Supply a protected ticket-page URL from your booking database. Your provider adapter must send the returned fields and record the delivery result.
import { Eventlayer } from "eventlayer";
const eventlayer = new Eventlayer();
export async function confirmationDraft(
ticketId: string,
ticketPageUrl: string,
) {
const ticket = await eventlayer.tickets.get({ ticketId: ticketId });
if (ticket.error) throw ticket.error;
if (ticket.data.status !== "assigned" || !ticket.data.attendee_id)
return null;
const attendee = await eventlayer.attendees.get({
attendeeId: ticket.data.attendee_id,
});
if (attendee.error) throw attendee.error;
if (!attendee.data.email) return null;
return {
messageKey: `${ticket.data.id}:${attendee.data.id}:confirmation`,
to: attendee.data.email,
subject: "Your event ticket is ready",
text: `Your registration is confirmed. View your ticket: ${ticketPageUrl}`,
};
}Skip null drafts and record the reason for review rather than inventing an
email address. Keep private ticket links out of logs. If you render HTML, escape
attendee and event text or use a template library that does so.
Use your email provider's idempotency mechanism where available with the stable message key. Otherwise, serialize sends and reconcile uncertain provider responses before retrying. A database "sent" flag alone cannot eliminate the crash window between a successful email send and saving that flag.
4. Schedule reminders and follow-ups
Store reminder jobs against the event's absolute start time and render the local time using its timezone. When an event changes, reschedule your pending jobs. Immediately before sending, re-fetch the ticket, assignment, and event details; skip deleted or cancelled admissions and avoid old recipients after reassignment.
For a follow-up, enqueue a job after ticket.checked_in, optionally with a delay
you choose. Apply your communication preferences and suppression rules; event
registration does not automatically opt someone into marketing campaigns.
Link to your ticket page instead of embedding a Wallet URL that expires in 24 hours. Generate a fresh Wallet link when the attendee visits that page.
Test and recover
- Create an assigned test ticket; receive one confirmation at your test inbox.
- Retry the same delivery and replay the event. Confirm the business message key prevents another send.
- Move the event time. Confirm the pending reminder changes accordingly.
- Reassign or remove a test ticket before the reminder runs; don't email the old recipient.
- Check in a disposable ticket. Confirm the correct follow-up job is scheduled.
- Simulate provider failure and a missing email address. Both should remain visible to your operations team.
Next steps
Use the same ticket IDs in CRM participation records, while keeping email delivery history in your own provider and database.