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 and the Scheduling component.
Create a scheduling configuration
Section titled “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.
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": "[email protected]", "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" } } } } } }'{ "ID": "<SCHEDULER_CONFIGURATION_ID>", "participants": [ { "name": "Nyla", "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.
Embed the booking widget
Section titled “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.
<!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>import { NylasScheduling } from "@nylas/react";
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.
Capture bookings
Section titled “Capture bookings”When a guest finishes the flow, the Scheduling component calls the Bookings endpoint for you and records a booking against the configuration. To act on that in your own server, subscribe to the booking.created webhook trigger 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.
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.
Things to know about embedding
Section titled “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, 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 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 so you can match it to your brand. For hosted pages, set
color,company_logo_url, andsubmit_button_labelin the configuration’sappearanceobject. - The 30-minute meeting length is configurable. The
duration_minutesfield 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
Section titled “What’s next”- Using the Scheduling component for slug embedding, error boundaries, and custom event handlers
- Manage bookings to create, reschedule, confirm, and cancel bookings from your server
- Nylas-hosted Scheduling Pages for branding, pre-filled forms, and the no-code
book.nylas.comoption - Using Nylas Scheduler for configurations, sessions, meeting types, and reminders
- booking.created notification for the full webhook payload schema