Scheduler sends booking confirmations for you, and you can’t change their wording or branding. An application-level workflow replaces them with your own HTML, using one template that applies to every user of your product.
This recipe covers the whole booking lifecycle: confirmation, reschedule, cancellation, pending approval, and reminder. If each of your customers needs their own branding, use Customize Scheduler email for each user instead.

How do I replace the Scheduler confirmation email?
Section titled “How do I replace the Scheduler confirmation email?”Create a template, point an application-level workflow at it, then turn off Nylas’s own email on the Scheduler configuration. The workflow fires for every grant in the application, so one template covers every user.
Start with the template. Set engine to handlebars explicitly, because the API default is mustache and mustache can’t call the formatDate helper you need for times.
curl -X POST 'https://api.us.nylas.com/v3/templates' \ -H "Authorization: Bearer $NYLAS_API_KEY" -H 'Content-Type: application/json' \ -d '{ "name": "Booking confirmed", "engine": "handlebars", "subject": "Confirmed: {{booking_info.title}}", "body": "<html>…</html>" }'body is a JSON string, so every quote and line break in the HTML needs escaping. Rather than escaping by hand, let jq build the request from the template file:
jq -n --rawfile body booking-created.html \ '{name: "Booking confirmed", engine: "handlebars", subject: "Confirmed: {{booking_info.title}}", body: $body}' \| curl -X POST 'https://api.us.nylas.com/v3/templates' \ -H "Authorization: Bearer $NYLAS_API_KEY" -H 'Content-Type: application/json' \ -d @-Then the workflow. delay is in minutes and 0 sends immediately.
The from address decides who the confirmation appears to come from. Omit it and the message sends through the host’s own grant, so the guest sees it arrive from the host’s real address, in the same thread as their other correspondence, with replies landing in the host’s inbox. That needs no domain setup, only mail send scopes on the grant. Set from and it sends through transactional send on a domain you registered, which gives every host the same branding. The Workflows overview compares both.
For booking confirmations the host’s own address is often the better choice, because a confirmation that looks personal gets replied to and a no-reply one doesn’t.
curl -X POST 'https://api.us.nylas.com/v3/workflows' \ -H "Authorization: Bearer $NYLAS_API_KEY" -H 'Content-Type: application/json' \ -d '{ "name": "Booking confirmed", "trigger_event": "booking.created", "template_id": "<TEMPLATE_ID>", "delay": 0, "is_enabled": true, "from": { "email": "[email protected]", "name": "Your Company" } }'Drop the from line entirely to send from the host’s mailbox instead. Everything else stays the same.
Repeat for each of the 5 booking triggers with its own template. booking.rescheduled and booking.reminder drop 4 fields that booking.created carries, and booking.cancelled has no booking_ref, so one shared template throws on whichever trigger lacks a field it references.
How do I stop Nylas sending its own email?
Section titled “How do I stop Nylas sending its own email?”Set disable_emails: true on the Scheduler configuration. Two fields control this independently, and your choice depends on whether guests also need the calendar provider’s invitation.
disable_emails | notify_participants | Messages the guest receives |
|---|---|---|
false | false | Nylas Scheduler email plus your workflow email |
true | false | Your workflow email only |
true | true | Your workflow email plus the Google or Microsoft calendar invitation |
Choose notify_participants: true when guests need a calendar reply button and a .ics attachment, which an HTML email can’t provide. The provider sends that invitation from the organizer’s own address rather than from Nylas, so it won’t carry your branding. Microsoft grants ignore notify_participants and always notify, so the workflow-only setup isn’t achievable on Microsoft.
{ "event_booking": { "title": "Meeting with ${invitee}", "booking_type": "booking", "disable_emails": true, "notify_participants": false, "reminders": [{ "type": "webhook", "minutes_before_event": 30 }] }, "scheduler": { "additional_fields": { "notify_individually": { "label": "Notify individually", "type": "metadata", "required": false, "default": "true" } } }}reminders with type: "webhook" is what makes booking.reminder fire, and without it that trigger never runs. Use booking_type: "organizer-confirmation" for booking.pending, which also requires scheduler.organizer_confirmation_url or the request returns 400. Updating a configuration uses PUT and replaces the whole object, so send the existing configuration back with your changes rather than a partial body.
How do I address each guest by name?
Section titled “How do I address each guest by name?”Set notify_individually on the booking. Nylas then sends one message per participant and populates recipient.email, recipient.first_name, and recipient.last_name for each. By default it sends a single message to all participants, leaving recipient undefined so any template referencing it fails to render.
The field has to be declared on the configuration first, as shown above. Passing it on the booking alone returns 400 Additional field 'notify_individually' not found in configuration.
{ "additional_fields": { "notify_individually": "true" }, "start_time": 1790182800, "end_time": 1790184600, "participants": [],}A booking with a guest named John Smith and an organizer named Nick then produces 2 messages from one template, reading Hi John, and Hi Nick,.
How does the template work?
Section titled “How does the template work?”The template is ordinary HTML with {{variable}} placeholders filled from the event payload. Four parts do the real work.
The greeting guards two levels. recipient is absent whenever notify_individually is off, and present but unnamed when a participant has no display name. The renderer throws on a missing parent, so a single guard isn’t enough.
{{#if recipient}}{{#if recipient.first_name}}Hi {{recipient.first_name}},{{else}}Hi there,{{/if}}{{else}}Hi there,{{/if}}The time resolves per recipient. booking_info is identical in every copy of a message and only recipient changes between them, so one timezone expression would give every recipient the same zone. lookup works as a nested expression, which is enough to pick a zone per person.
{{#if recipient}}{{#if booking_info.additional_fields}}{{#if (lookup booking_info.additional_fields recipient.email)}} {{ formatDate booking_info.start_time (lookup booking_info.additional_fields recipient.email) "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}} {{#if booking_info.guest_timezone}}{{ formatDate booking_info.start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{ formatDate booking_info.start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{/if}}{{/if}}{{/if}}{{/if}}That resolves in 4 steps: the recipient’s own timezone, then guest_timezone, then organizer_timezone, then UTC. guest_timezone is only set when the guest supplies one and is an empty string otherwise, which formatDate would silently treat as UTC, so the {{#if}} skips it when empty. organizer_timezone carries the configuration’s event_booking.timezone, and if that’s empty too, formatDate uses UTC.
Supply the per-recipient dictionary in the booking request, because the configuration’s default value isn’t applied to the payload. Email addresses are valid field keys.
"additional_fields": { "notify_individually": "true",}One booking with a host in America/Chicago and a guest in America/New_York then produces 1:00 PM EDT for the guest and 12:00 PM CDT for the host, from the same template. Leave the guest out of the dictionary and they get organizer_timezone instead, because guest_timezone is empty on bookings made through the API.
Optional fields are wrapped. location arrives as an empty string on many bookings, so the Where row is wrapped in {{#if booking_info.location}} and disappears cleanly rather than leaving a dangling label.
The locale is a variable. formatDate takes a timestamp, an IANA timezone, a Luxon token string, and a locale, and all 4 accept variables. Passing booking_info.guest_language renders miércoles 23 septiembre 2026 for es and mercredi 23 septembre 2026 for fr with no extra work.
The complete template
Section titled “The complete template”This is the booking.created template from the screenshot above. The other 4 booking triggers follow the same structure with their own fields.
<html>
<head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Your meeting is confirmed</title> <style> body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; line-height: 1.6; color: #333333; margin: 0; padding: 0; background-color: #f9fbfe; font-size: 16px; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { text-align: center; padding: 20px 0; }
.content { background-color: #ffffff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); }
.detail-label { color: #666666; font-size: 14px; padding: 6px 16px 6px 0; vertical-align: top; white-space: nowrap; }
.detail-value { padding: 6px 0; vertical-align: top; }
.footer { text-align: center; padding: 20px 0; color: #666666; font-size: 14px; }
@media only screen and (max-width: 600px) { .container { width: 100% !important; padding: 10px !important; }
.content { padding: 20px !important; } } </style></head>
<body> <div class="container"> <div class="header"> <img src="https://brand.nylas.com/assets/site_images/Nylas-Logo_Horizontal-Blue.png" alt="Nylas Logo" style="max-width: 150px;" /> </div>
<div class="content"> <h1 style="margin-top: 0; color: #1A1A1A;">Your meeting is confirmed</h1>
{{#if recipient}}{{#if recipient.first_name}}<p>Hi {{recipient.first_name}},</p>{{else}}<p>Hi there,</p>{{/if}}{{else}}<p>Hi there,</p>{{/if}}
<p> <strong>{{booking_info.title}}</strong> is booked. The details are below, and the invitation is already on your calendar. </p>
<hr style="border: 0; border-top: 1px solid #eeeeee; margin: 20px 0;" />
<h2 style="color: #4D4D4D; font-weight: 500;">Meeting details</h2>
<table cellpadding="0" cellspacing="0" border="0" style="width: 100%;"> <tr> <td class="detail-label">When</td> <td class="detail-value"> {{#if recipient}}{{#if booking_info.additional_fields}}{{#if (lookup booking_info.additional_fields recipient.email)}}{{ formatDate booking_info.start_time (lookup booking_info.additional_fields recipient.email) "EEEE d LLLL yyyy, h:mm a ZZZZ" "en" }}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" "en" }}{{else}}{{ formatDate booking_info.start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" "en" }}{{/if}}{{/if}}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" "en" }}{{else}}{{ formatDate booking_info.start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" "en" }}{{/if}}{{/if}}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" "en" }}{{else}}{{ formatDate booking_info.start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" "en" }}{{/if}}{{/if}} </td> </tr> <tr> <td class="detail-label">Duration</td> <td class="detail-value">{{booking_info.duration}} minutes</td> </tr> {{#if booking_info.location}} <tr> <td class="detail-label">Where</td> <td class="detail-value"><a href="{{booking_info.location}}" style="color: #0D6EFD;">{{booking_info.location}}</a></td> </tr> {{/if}} <tr> <td class="detail-label">Who</td> <td class="detail-value"> {{#each booking_info.participants}}{{name}} <{{email}}>{{#unless @last}}<br />{{/unless}}{{/each}} </td> </tr> </table>
<div style="text-align: center; margin: 30px 0;"> <a href="{{booking_info.participant_rescheduling_url}}" style="background-color: #0D6EFD; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; display: inline-block;">Reschedule</a> </div>
<p style="font-size: 14px; color: #666666; text-align: center;"> Can no longer make it? <a href="{{booking_info.participant_cancellation_url}}" style="color: #0D6EFD;">Cancel this meeting</a>. </p> </div>
<div class="footer"> <p>© 2026 <a href="https://www.nylas.com/" style="color: #0D6EFD;">Nylas</a></p> <p style="font-size: 12px; color: #999999; margin-top: 4px;"> Booking reference: {{booking_info.event_id}} </p> </div> </div></body>
</html><html>
<head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Your meeting moved</title> <style> body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; line-height: 1.6; color: #333333; margin: 0; padding: 0; background-color: #f9fbfe; font-size: 16px; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { text-align: center; padding: 20px 0; }
.content { background-color: #ffffff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); }
.detail-label { color: #666666; font-size: 14px; padding: 6px 16px 6px 0; vertical-align: top; white-space: nowrap; }
.detail-value { padding: 6px 0; vertical-align: top; }
.footer { text-align: center; padding: 20px 0; color: #666666; font-size: 14px; }
@media only screen and (max-width: 600px) { .container { width: 100% !important; padding: 10px !important; }
.content { padding: 20px !important; } } </style></head>
<body> <div class="container"> <div class="header"> <img src="https://brand.nylas.com/assets/site_images/Nylas-Logo_Horizontal-Blue.png" alt="Nylas Logo" style="max-width: 150px;" /> </div>
<div class="content"> <h1 style="margin-top: 0; color: #1A1A1A;">Your meeting has moved</h1>
{{#if recipient}}{{#if recipient.first_name}}<p>Hi {{recipient.first_name}},</p>{{else}}<p>Hi there,</p>{{/if}}{{else}}<p>Hi there,</p>{{/if}}
<p><strong>{{booking_info.title}}</strong> has been rescheduled. The new time is below and your calendar has already been updated.</p>
<hr style="border: 0; border-top: 1px solid #eeeeee; margin: 20px 0;" />
<h2 style="color: #4D4D4D; font-weight: 500;">Meeting details</h2>
<table cellpadding="0" cellspacing="0" border="0" style="width: 100%;"> {{#if booking_info.old_start_time}}<tr><td class="detail-label">Previously</td><td class="detail-value"><span style="color: #999999; text-decoration: line-through;">{{#if recipient}}{{#if booking_info.additional_fields}}{{#if (lookup booking_info.additional_fields recipient.email)}}{{ formatDate booking_info.old_start_time (lookup booking_info.additional_fields recipient.email) "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.old_start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{ formatDate booking_info.old_start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{/if}}{{/if}}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.old_start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{ formatDate booking_info.old_start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{/if}}{{/if}}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.old_start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{ formatDate booking_info.old_start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{/if}}{{/if}}</span></td></tr>{{/if}} <tr><td class="detail-label">Now</td><td class="detail-value">{{#if recipient}}{{#if booking_info.additional_fields}}{{#if (lookup booking_info.additional_fields recipient.email)}}{{ formatDate booking_info.start_time (lookup booking_info.additional_fields recipient.email) "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{ formatDate booking_info.start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{/if}}{{/if}}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{ formatDate booking_info.start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{/if}}{{/if}}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{ formatDate booking_info.start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{/if}}{{/if}}</td></tr> <tr><td class="detail-label">Duration</td><td class="detail-value">{{booking_info.duration}} minutes</td></tr> {{#if booking_info.location}}<tr><td class="detail-label">Where</td><td class="detail-value"><a href="{{booking_info.location}}" style="color: #0D6EFD;">{{booking_info.location}}</a></td></tr>{{/if}} <tr><td class="detail-label">Who</td><td class="detail-value">{{#each booking_info.participants}}{{name}} <{{email}}>{{#unless @last}}<br />{{/unless}}{{/each}}</td></tr> </table> <div style="text-align: center; margin: 30px 0;"><a href="{{booking_info.participant_rescheduling_url}}" style="background-color: #0D6EFD; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; display: inline-block;">Reschedule again</a></div> <p style="font-size: 14px; color: #666666; text-align: center;">Can no longer make it? <a href="{{booking_info.participant_cancellation_url}}" style="color: #0D6EFD;">Cancel this meeting</a>.</p> </div>
<div class="footer"> <p>© 2026 <a href="https://www.nylas.com/" style="color: #0D6EFD;">Nylas</a></p> <p style="font-size: 12px; color: #999999; margin-top: 4px;"> Booking reference: {{booking_info.event_id}} </p> </div> </div></body>
</html><html>
<head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Your meeting was cancelled</title> <style> body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; line-height: 1.6; color: #333333; margin: 0; padding: 0; background-color: #f9fbfe; font-size: 16px; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { text-align: center; padding: 20px 0; }
.content { background-color: #ffffff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); }
.detail-label { color: #666666; font-size: 14px; padding: 6px 16px 6px 0; vertical-align: top; white-space: nowrap; }
.detail-value { padding: 6px 0; vertical-align: top; }
.footer { text-align: center; padding: 20px 0; color: #666666; font-size: 14px; }
@media only screen and (max-width: 600px) { .container { width: 100% !important; padding: 10px !important; }
.content { padding: 20px !important; } } </style></head>
<body> <div class="container"> <div class="header"> <img src="https://brand.nylas.com/assets/site_images/Nylas-Logo_Horizontal-Blue.png" alt="Nylas Logo" style="max-width: 150px;" /> </div>
<div class="content"> <h1 style="margin-top: 0; color: #1A1A1A;">Your meeting was cancelled</h1>
{{#if recipient}}{{#if recipient.first_name}}<p>Hi {{recipient.first_name}},</p>{{else}}<p>Hi there,</p>{{/if}}{{else}}<p>Hi there,</p>{{/if}}
<p><strong>{{booking_info.title}}</strong> has been cancelled and removed from your calendar.</p>{{#if booking_info.cancellation_reason}}<p><strong>Reason:</strong> {{booking_info.cancellation_reason}}</p>{{/if}}
<hr style="border: 0; border-top: 1px solid #eeeeee; margin: 20px 0;" />
<h2 style="color: #4D4D4D; font-weight: 500;">Meeting details</h2>
<table cellpadding="0" cellspacing="0" border="0" style="width: 100%;"> <tr><td class="detail-label">Was scheduled for</td><td class="detail-value">{{#if recipient}}{{#if booking_info.additional_fields}}{{#if (lookup booking_info.additional_fields recipient.email)}}{{ formatDate booking_info.start_time (lookup booking_info.additional_fields recipient.email) "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{ formatDate booking_info.start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{/if}}{{/if}}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{ formatDate booking_info.start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{/if}}{{/if}}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{ formatDate booking_info.start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{/if}}{{/if}}</td></tr> <tr><td class="detail-label">Duration</td><td class="detail-value">{{booking_info.duration}} minutes</td></tr> <tr><td class="detail-label">Who</td><td class="detail-value">{{#each booking_info.participants}}{{name}} <{{email}}>{{#unless @last}}<br />{{/unless}}{{/each}}</td></tr> </table> <div style="text-align: center; margin: 30px 0;"><a href="{{booking_info.participant_rescheduling_url}}" style="background-color: #0D6EFD; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; display: inline-block;">Book a new time</a></div> <p style="font-size: 14px; color: #666666; text-align: center;">You don't need to do anything else.</p> </div>
<div class="footer"> <p>© 2026 <a href="https://www.nylas.com/" style="color: #0D6EFD;">Nylas</a></p> <p style="font-size: 12px; color: #999999; margin-top: 4px;"> Booking reference: {{booking_info.event_id}} </p> </div> </div></body>
</html><html>
<head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Booking request received</title> <style> body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; line-height: 1.6; color: #333333; margin: 0; padding: 0; background-color: #f9fbfe; font-size: 16px; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { text-align: center; padding: 20px 0; }
.content { background-color: #ffffff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); }
.detail-label { color: #666666; font-size: 14px; padding: 6px 16px 6px 0; vertical-align: top; white-space: nowrap; }
.detail-value { padding: 6px 0; vertical-align: top; }
.footer { text-align: center; padding: 20px 0; color: #666666; font-size: 14px; }
@media only screen and (max-width: 600px) { .container { width: 100% !important; padding: 10px !important; }
.content { padding: 20px !important; } } </style></head>
<body> <div class="container"> <div class="header"> <img src="https://brand.nylas.com/assets/site_images/Nylas-Logo_Horizontal-Blue.png" alt="Nylas Logo" style="max-width: 150px;" /> </div>
<div class="content"> <h1 style="margin-top: 0; color: #1A1A1A;">Your booking request was received</h1>
{{#if recipient}}{{#if recipient.first_name}}<p>Hi {{recipient.first_name}},</p>{{else}}<p>Hi there,</p>{{/if}}{{else}}<p>Hi there,</p>{{/if}}
<p>We've received your request for <strong>{{booking_info.title}}</strong>. It isn't confirmed yet — the organizer needs to approve it, and you'll get another email as soon as they do.</p>
<hr style="border: 0; border-top: 1px solid #eeeeee; margin: 20px 0;" />
<h2 style="color: #4D4D4D; font-weight: 500;">Meeting details</h2>
<table cellpadding="0" cellspacing="0" border="0" style="width: 100%;"> <tr><td class="detail-label">When</td><td class="detail-value">{{#if recipient}}{{#if booking_info.additional_fields}}{{#if (lookup booking_info.additional_fields recipient.email)}}{{ formatDate booking_info.start_time (lookup booking_info.additional_fields recipient.email) "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{ formatDate booking_info.start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{/if}}{{/if}}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{ formatDate booking_info.start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{/if}}{{/if}}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{ formatDate booking_info.start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{/if}}{{/if}}</td></tr> <tr><td class="detail-label">Duration</td><td class="detail-value">{{booking_info.duration}} minutes</td></tr> {{#if booking_info.location}}<tr><td class="detail-label">Where</td><td class="detail-value"><a href="{{booking_info.location}}" style="color: #0D6EFD;">{{booking_info.location}}</a></td></tr>{{/if}} <tr><td class="detail-label">Who</td><td class="detail-value">{{#each booking_info.participants}}{{name}} <{{email}}>{{#unless @last}}<br />{{/unless}}{{/each}}</td></tr> </table> <div style="text-align: center; margin: 30px 0;"><a href="{{booking_info.participant_cancellation_url}}" style="background-color: #0D6EFD; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; display: inline-block;">Withdraw request</a></div> <p style="font-size: 14px; color: #666666; text-align: center;">Nothing is on your calendar until the organizer confirms.</p> </div>
<div class="footer"> <p>© 2026 <a href="https://www.nylas.com/" style="color: #0D6EFD;">Nylas</a></p> <p style="font-size: 12px; color: #999999; margin-top: 4px;"> Booking reference: {{booking_info.event_id}} </p> </div> </div></body>
</html><html>
<head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Your meeting starts soon</title> <style> body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; line-height: 1.6; color: #333333; margin: 0; padding: 0; background-color: #f9fbfe; font-size: 16px; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { text-align: center; padding: 20px 0; }
.content { background-color: #ffffff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); }
.detail-label { color: #666666; font-size: 14px; padding: 6px 16px 6px 0; vertical-align: top; white-space: nowrap; }
.detail-value { padding: 6px 0; vertical-align: top; }
.footer { text-align: center; padding: 20px 0; color: #666666; font-size: 14px; }
@media only screen and (max-width: 600px) { .container { width: 100% !important; padding: 10px !important; }
.content { padding: 20px !important; } } </style></head>
<body> <div class="container"> <div class="header"> <img src="https://brand.nylas.com/assets/site_images/Nylas-Logo_Horizontal-Blue.png" alt="Nylas Logo" style="max-width: 150px;" /> </div>
<div class="content"> <h1 style="margin-top: 0; color: #1A1A1A;">Your meeting starts soon</h1>
{{#if recipient}}{{#if recipient.first_name}}<p>Hi {{recipient.first_name}},</p>{{else}}<p>Hi there,</p>{{/if}}{{else}}<p>Hi there,</p>{{/if}}
<p>A reminder that <strong>{{booking_info.title}}</strong> is coming up.</p>
<hr style="border: 0; border-top: 1px solid #eeeeee; margin: 20px 0;" />
<h2 style="color: #4D4D4D; font-weight: 500;">Meeting details</h2>
<table cellpadding="0" cellspacing="0" border="0" style="width: 100%;"> <tr><td class="detail-label">When</td><td class="detail-value">{{#if recipient}}{{#if booking_info.additional_fields}}{{#if (lookup booking_info.additional_fields recipient.email)}}{{ formatDate booking_info.start_time (lookup booking_info.additional_fields recipient.email) "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{ formatDate booking_info.start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{/if}}{{/if}}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{ formatDate booking_info.start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{/if}}{{/if}}{{else}}{{#if booking_info.guest_timezone}}{{ formatDate booking_info.start_time booking_info.guest_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{else}}{{ formatDate booking_info.start_time booking_info.organizer_timezone "EEEE d LLLL yyyy, h:mm a ZZZZ" booking_info.guest_language }}{{/if}}{{/if}}</td></tr> <tr><td class="detail-label">Duration</td><td class="detail-value">{{booking_info.duration}} minutes</td></tr> {{#if booking_info.location}}<tr><td class="detail-label">Where</td><td class="detail-value"><a href="{{booking_info.location}}" style="color: #0D6EFD;">{{booking_info.location}}</a></td></tr>{{/if}} <tr><td class="detail-label">Who</td><td class="detail-value">{{#each booking_info.participants}}{{name}} <{{email}}>{{#unless @last}}<br />{{/unless}}{{/each}}</td></tr> </table> <div style="text-align: center; margin: 30px 0;"><a href="{{booking_info.location}}" style="background-color: #0D6EFD; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; display: inline-block;">Join the meeting</a></div> <p style="font-size: 14px; color: #666666; text-align: center;">Need to change it? <a href="{{booking_info.participant_rescheduling_url}}" style="color: #0D6EFD;">Reschedule</a> or <a href="{{booking_info.participant_cancellation_url}}" style="color: #0D6EFD;">cancel</a>.</p> </div>
<div class="footer"> <p>© 2026 <a href="https://www.nylas.com/" style="color: #0D6EFD;">Nylas</a></p> <p style="font-size: 12px; color: #999999; margin-top: 4px;"> Booking reference: {{booking_info.event_id}} </p> </div> </div></body>
</html>Render each one with POST /v3/templates/render before enabling its workflow. A missing variable returns 400 and sends nothing, with no error on the booking request, so Why isn’t my workflow sending email? is worth reading before you go live.
What’s next
Section titled “What’s next”- Customize Scheduler email for each user for per-customer branding and what it costs to run
- Tell Scheduler attendees the meeting is recorded when bookings create a Notetaker session
- Why isn’t my workflow sending email? for the strict rendering rules
- Customize the booking flow for booking form fields and confirmation redirects
- Scheduler notifications for the full payload of each booking trigger