# How to embed a scheduling page

Source: https://developer.nylas.com/docs/cookbook/scheduler/embed-scheduling-page/

You want self-service booking inside your own product, the kind tools like Calendly popularized, not a third-party link that sends users off-site. Building that yourself means writing availability math, calendar sync, time-zone handling, and a booking form. With the Nylas Scheduler you skip all that: create one configuration, embed a single web component, and your app has a working booking page.

This recipe covers the fastest path from zero to a live booking page. It pairs two existing references you'll want open while you build: [creating a configuration](/docs/v3/scheduler/#create-a-configuration) and [the Scheduling component](/docs/v3/scheduler/using-scheduling-component/).

## Create a scheduling configuration

A scheduling configuration is the saved settings object that powers a booking page: who guests can book, which calendar to check for availability, the meeting duration, and the event details. You create one with a single `POST /v3/grants/{grant_id}/scheduling/configurations` request, and the response returns a `configuration_id` that the embedded widget references.

The request below registers an organizer, points availability at their `primary` calendar, and sets a 30-minute meeting that creates a Zoom link per booking. The `configuration_id` it returns is the only value the booking widget needs, so store it once and reuse it across every page that embeds this configuration.

```bash
curl --compressed --request POST \
  --url "https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/scheduling/configurations" \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "requires_session_auth": false,
    "participants": [{
      "name": "Nyla",
      "email": "nyla@example.com",
      "is_organizer": true,
      "availability": {
        "calendar_ids": ["primary"]
      },
      "booking": {
        "calendar_id": "primary"
      }
    }],
    "availability": {
      "duration_minutes": 30
    },
    "event_booking": {
      "title": "Testing Scheduler",
      "hide_participants": false,
      "conferencing": {
        "provider": "Zoom Meeting",
        "autocreate": {
          "conf_grant_id": "<NYLAS_GRANT_ID>",
          "conf_settings": {
            "settings": {
              "join_before_host": true,
              "waiting_room": false,
              "mute_upon_entry": false,
              "auto_recording": "none"
            }
          }
        }
      }
    }
  }'

```

```json
{
  "ID": "<SCHEDULER_CONFIGURATION_ID>",
  "participants": [
    {
      "name": "Nyla",
      "email": "nyla@example.com",
      "is_organizer": true,
      "availability": {
        "calendar_ids": ["primary"]
      },
      "booking": {
        "calendar_id": "primary"
      }
    }
  ],
  "availability": {
    "duration_minutes": 30
  },
  "event_booking": {
    "title": "Testing Scheduler"
  }
}


```

By default the configuration is public (`requires_session_auth: false`), so anyone with the page can book. For a deeper walkthrough of availability rules, participants, and round-robin setups, see [create a Scheduler booking config](/docs/cookbook/use-cases/build/scheduler-booking-config/).

## Embed the booking widget

The booking widget is the `<nylas-scheduling>` web component (or `NylasScheduling` in React from the `@nylas/react` package). It renders all 4 stages of the guest-facing flow: a calendar, available time slots, the booking form, and the confirmation screen. You point it at your `configuration_id` and the component handles availability checks and booking creation against the Scheduler API.

Passing the configuration ID directly is the approach Nylas recommends. The component loads faster and is more secure than passing a slug, since it gains direct access to the configuration. The snippet below embeds the widget in plain HTML by loading the component from a content delivery network, no build step required.

```html [embedWidget-HTML/Vanilla JS]
<!DOCTYPE html>
<html>
  <head>
    <title>Book a meeting</title>
    <script src="https://cdn.jsdelivr.net/npm/@nylas/react@latest/dist/cdn/nylas-scheduling/nylas-scheduling.es.js"></script>
  </head>
  <body>
    <nylas-scheduling
      configuration-id="<CONFIGURATION_ID>"
      default-language="en"
    >
    </nylas-scheduling>
  </body>
</html>
```

```tsx
function BookingPage() {
  return (
    <NylasScheduling
      configurationId="<CONFIGURATION_ID>"
      defaultLanguage="en"
    />
  );
}
```

That's the whole integration for a default booking page. For slug-based embedding, error boundaries, and event handlers, read [using the Scheduling component](/docs/v3/scheduler/using-scheduling-component/).

## Capture bookings

When a guest finishes the flow, the Scheduling component calls the [Bookings endpoint](/docs/reference/api/bookings/) for you and records a booking against the configuration. To act on that in your own server, subscribe to the [`booking.created` webhook trigger](/docs/reference/notifications/scheduler/booking-created/) so Nylas sends a real-time payload to your server the moment a guest confirms a booking.

You register a webhook with one `POST /v3/webhooks` request listing the triggers you care about. Scheduler emits five booking triggers in total: `booking.created`, `booking.pending`, `booking.rescheduled`, `booking.cancelled`, and `booking.reminder`. Your endpoint must be live and return a `200` before the subscription activates.

```bash
curl --request POST \
  --url "https://api.us.nylas.com/v3/webhooks" \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "trigger_types": ["booking.created"],
    "webhook_url": "<WEBHOOK_URL>"
  }'
```

Use the payload to write the booking to your database, kick off a follow-up email, or sync it to your customer records. For creating, confirming, rescheduling, and cancelling bookings from your own server, see [manage bookings](/docs/cookbook/use-cases/build/manage-bookings/).

## Things to know about embedding

The biggest decision is which surface to use. A Nylas page at `book.nylas.com/<SLUG>` needs zero front-end code, while the embedded `<nylas-scheduling>` component keeps the booking flow inside your domain and styling. Both read the same configuration, so you can ship a hosted page in minutes and swap to the embedded widget later without recreating anything.

A few things to watch for when you embed:

- **The widget needs a connected calendar.** The configuration's availability rules check a real calendar grant. Without a connected [grant](/docs/v3/auth/), the widget has no Free/Busy data and shows no slots.
- **Auth mode depends on visibility.** Public configurations (`requires_session_auth: false`) let anyone book with the configuration ID or slug alone. Private configurations require a [session](/docs/v3/scheduler/#optional-create-a-session) before the widget can read availability or write bookings.
- **The widget handles reschedule and cancel.** Scheduler can add reschedule and cancel links to the confirmation email, so guests manage their own bookings without contacting you.
- **Theming uses CSS shadow parts.** The component exposes [CSS shadow parts](https://www.w3.org/TR/css-shadow-parts-1/) so you can match it to your brand. For hosted pages, set `color`, `company_logo_url`, and `submit_button_label` in the configuration's `appearance` object.
- **The 30-minute meeting length is configurable.** The `duration_minutes` field sets meeting length, and you can change it per configuration at any time with an Update Configuration request.

If you only need a shareable link and no in-app UI, the hosted page is the lighter option. If the booking flow has to feel native to your product, embed the component.

## What's next

- [Using the Scheduling component](/docs/v3/scheduler/using-scheduling-component/) for slug embedding, error boundaries, and custom event handlers
- [Manage bookings](/docs/cookbook/use-cases/build/manage-bookings/) to create, reschedule, confirm, and cancel bookings from your server
- [Nylas-hosted Scheduling Pages](/docs/v3/scheduler/hosted-scheduling-pages/) for branding, pre-filled forms, and the no-code `book.nylas.com` option
- [Using Nylas Scheduler](/docs/v3/scheduler/) for configurations, sessions, meeting types, and reminders
- [booking.created notification](/docs/reference/notifications/scheduler/booking-created/) for the full webhook payload schema