# Customize the booking flow

Source: https://developer.nylas.com/docs/cookbook/scheduler/customize-booking-flow/

The default Scheduler booking flow asks for a name and an email, shows a generic confirmation, and stops there. That's rarely enough for a real product. You probably want to collect a phone number, send people to your own thank-you page, let them reschedule without emailing you, and match your brand colors. Every one of those is a configurable part of the flow.

This recipe walks through the four customizations developers reach for most: form fields, the confirmation step, reschedule and cancel pages, and theming. Each one works through the same `nylas-scheduling` web component or the [Scheduler Editor](/docs/v3/scheduler/using-scheduler-editor-component/), so you can mix the approaches that fit your stack.

## Add and configure booking form fields

The booking form collects guest details before a booking is created. You control it two ways: define an `additional_fields` object on the Configuration so the form renders the inputs automatically, or set the `bookingInfo` property on the `nylas-scheduling` component to prefill values. About four field types cover most cases: `text`, `email`, `phone_number`, and `dropdown`.

Define `additional_fields` in a [Create Configuration](/docs/reference/api/configurations/post-configurations/) or [Update Configuration](/docs/reference/api/configurations/put-configurations-id/) request. Each entry takes a `label`, a `type`, an optional `options` array for dropdowns, and a `required` flag. The labels double as [template variables](/docs/v3/scheduler/customize-booking-flows/) you can drop into event titles.

```json
{
  "additional_fields": {
    "company_name": {
      "label": "Company name",
      "type": "text",
      "required": true
    },
    "meeting_type": {
      "label": "Type of meeting",
      "type": "dropdown",
      "options": ["Sales call", "Support", "Demo"],
      "required": true
    }
  }
}
```

If you already know who's booking, prefill the form instead of asking. Set `bookingInfo` on the component with a `primaryParticipant`, optional `guests`, and `additionalFields`. You can mark any value read-only so guests can't edit it, which is useful when you've authenticated the user already. Every prefilled field accepts a `readOnly` flag.

```html
<nylas-scheduling />
<script type="module">
  const nylasScheduling = document.querySelector("nylas-scheduling");

  nylasScheduling.bookingInfo = {
    primaryParticipant: {
      name: "Leyah Miller",
      email: "leyah@example.com",
      nameReadOnly: true,
      emailReadOnly: true,
    },
    additionalFields: {
      additional_email: {
        value: "nyla@example.com",
        type: "email",
        readOnly: true,
      },
    },
  };
</script>
```

## Set the confirmation and redirect

After a booking is created, the component shows a built-in confirmation panel. You have two ways to customize it. To keep guests inside your app, rewrite the confirmation text. To send them somewhere else entirely, redirect to your own page. Both paths replace the same default screen, and only one of them changes the URL.

To customize the confirmation copy without leaving the component, override the `bookNowButton` label and `bookingConfirmedDescription` text through the `configSettingsLoaded` event. The handler reads `submit_button_label` and `thank_you_message` from the `appearance` object and applies them across all eight supported language codes.

```html
<nylas-scheduling />
<script type="module">
  const nylasScheduling = document.querySelector("nylas-scheduling");
  const LANGUAGE_CODES = ["en", "es", "fr", "de", "sv", "zhcn", "ja", "nl"];

  nylasScheduling.eventOverrides = {
    configSettingsLoaded: async (event, connector) => {
      const { settings } = event.detail;
      const { submit_button_label, thank_you_message } = settings.data.appearance;

      const overrides = {
        bookNowButton: submit_button_label,
        bookingConfirmedDescription: thank_you_message,
      };

      nylasScheduling.localization = LANGUAGE_CODES.reduce((acc, code) => {
        acc[code] = overrides;
        return acc;
      }, {});
    },
  };
</script>
```

To send guests to a branded confirmation page instead, set `scheduler.confirmation_redirect_url` on the Configuration. This skips the in-component panel and forwards the guest to your URL after a successful booking. One redirect URL applies per Configuration.

```bash {8}
curl --request PUT \
  --url "https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/scheduling/configurations/<SCHEDULER_CONFIGURATION_ID>" \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "scheduler": {
      "confirmation_redirect_url": "https://www.example.com/booking-confirmed"
    }
  }'
```

## Enable reschedule and cancel

Reschedule and cancel let guests manage a booking without contacting you. Both rely on a booking reference that Nylas generates when a booking is created. You add two URLs to the Configuration, then build a page for each that renders the `nylas-scheduling` component pointed at the right booking. The reference appears in two places: the page URL and the [Scheduler notifications](/docs/reference/notifications/scheduler/).

Add `scheduler.rescheduling_url` and `scheduler.cancellation_url` to the Configuration. Nylas substitutes the `:booking_ref` placeholder with the real reference for each booking, then surfaces both links on the confirmation page and in confirmation emails. These two URLs cover the entire post-booking lifecycle.

```bash {3,4}
{
  "scheduler": {
    "rescheduling_url": "https://www.example.com/rescheduling/:booking_ref",
    "cancellation_url": "https://www.example.com/cancelling/:booking_ref"
  }
}
```

On the reschedule page, set `rescheduleBookingRef`. On the cancel page, set `cancelBookingRef`. Each page reads the reference from its URL and loads the matching booking. The two snippets are nearly identical, differing only in the single prop that drives the action.

```tsx
<NylasScheduling
  rescheduleBookingRef="<SCHEDULER_BOOKING_REFERENCE>"
  // Set sessionId if the Configuration is private (requires_session_auth=true).
  // sessionId={"<SCHEDULER_SESSION_ID>"}
/>;

<NylasScheduling cancelBookingRef="<SCHEDULER_BOOKING_REFERENCE>" />;
```

To react to these actions in your backend, subscribe to the `booking.rescheduled` and `booking.cancelled` [webhook triggers](/docs/reference/notifications/scheduler/). Nylas fires them every time a guest changes or drops a booking, so you can update records, free calendar slots, or notify staff. Both triggers carry the booking reference, which keeps your handler stateless across all incoming events.

## Theme the scheduler

Theming makes the booking page look like part of your product instead of a third-party widget. The Scheduler UI components support [CSS shadow parts](https://www.w3.org/TR/css-shadow-parts-1/), so you can target internal elements from your own stylesheet without forking the component. There are dozens of named parts available, listed in the [Scheduler UI references](/docs/reference/ui/).

Use the `::part()` selector to style specific pieces of a component. This example sets the background and text color of the selected date on the booking calendar. Shadow parts give you precise control while keeping the component's internal structure untouched.

```css
nylas-scheduling::part(ndp__date--selected) {
  background-color: #2563eb;
  color: #ffffff;
}
```

For brand colors driven by the Configuration, apply `themeConfig` instead. Read the saved `color` from the `appearance` object in the `configSettingsLoaded` handler, then map it onto Nylas CSS variables. This keeps theming centralized so a single saved value updates every booking page at once.

```html
<nylas-scheduling />
<script type="module">
  const nylasScheduling = document.querySelector("nylas-scheduling");

  nylasScheduling.eventOverrides = {
    configSettingsLoaded: async (event, connector) => {
      const { color } = event.detail.settings.data.appearance;
      if (color) {
        nylasScheduling.themeConfig = {
          "--nylas-primary": color,
          "--nylas-base-500": color,
        };
      }
    },
  };
</script>
```

## Things to know about customization

The two embedding paths differ in what they expose. The `nylas-scheduling` component gives you full control over props, event handlers, and styling, so almost everything in this recipe applies. A Nylas-hosted Scheduling Page reads the same Configuration but locks the surrounding UI, so theming there comes only from the saved `appearance` object, not from `::part()` selectors or `themeConfig`. Pick the component when you need pixel control, and the hosted page when you want zero front-end code.

A few more details worth knowing:

- **Themeable vs. fixed.** Colors, the submit button label, the thank-you message, and shadow-part styling are all themeable. Layout structure and field ordering within a tab are fixed unless you switch the Editor to [`composable` mode](/docs/v3/scheduler/using-scheduler-editor-component/).
- **Required vs. optional fields.** A field's `required` flag is enforced before a booking is created, and a required field whose label feeds a template variable must stay required, or the variable drops out.
- **Localization.** The `localization` property supports eight language codes (`en`, `es`, `fr`, `de`, `sv`, `zhcn`, `ja`, `nl`). Custom confirmation copy applies per language, so set the same overrides across every code your audience uses.
- **Notifications.** Nylas sends confirmation, reschedule, and cancel emails by default. Set `disable_emails` to `true` on the Configuration if you'd rather send your own from a `booking.created` webhook handler.
- **Conferencing.** Add `event_booking.conferencing` to attach a Google Meet, Microsoft Teams, or Zoom link automatically, which is also the prerequisite for [Notetaker on Scheduler bookings](/docs/v3/scheduler/scheduler-notetaker-integration/).

To let organizers theme their own pages, add a `custom-page-style-inputs` slot to the Scheduler Editor with input elements such as `input-color-picker` and `input-image-url`. The reference for these styling inputs lives in the [page styling element docs](/docs/reference/ui/page-styling/).

## What's next

- [Embed a scheduling page](/docs/cookbook/scheduler/embed-scheduling-page/) in your app
- [Manage bookings](/docs/cookbook/use-cases/build/manage-bookings/) programmatically
- [Customize Scheduler booking flows](/docs/v3/scheduler/customize-booking-flows/) with pre-bookings and redirects
- [Scheduler overview](/docs/v3/scheduler/) for setup and Configuration basics