You’re building a feature where a visitor picks a time and lands a confirmed meeting on a calendar. Sounds small. Then the edge cases pile up: two people grab the same slot, an attendee’s timezone is wrong, the host’s lunch block isn’t honored, and nobody gets a video link. Hand-rolling that on top of raw calendar reads turns a one-week feature into a multi-month project that you then maintain forever.
A scheduling API exists to absorb that work. This page defines what a scheduling API actually does, breaks down the four jobs it handles, and shows where the Nylas Scheduler API fits when you’d rather not rebuild a booking engine from scratch.
What is a scheduling API and how is it used in appointment-based applications?
Section titled “What is a scheduling API and how is it used in appointment-based applications?”A scheduling API runs the full booking workflow: it computes real-time availability across one or more people, returns bookable time slots, captures the chosen slot, prevents double-booking at confirmation, and writes the event to every calendar involved. Appointment apps use it to power the “pick a time” page that turns a visitor into a confirmed meeting in seconds.
Think of it as four jobs bundled into one surface. A calendar API gives you raw event CRUD and stops there. A scheduling API composes those primitives into a workflow, which is the difference between a building block and a finished feature. The Nylas Scheduler API splits this across three calls: a Configuration defines the bookable meeting, GET /v3/scheduling/availability returns open slots, and POST /v3/scheduling/bookings confirms the booking. For the deeper line between the two layers, see scheduling API vs calendar API.
How is availability computed across attendees?
Section titled “How is availability computed across attendees?”Availability computation reads every participant’s calendar, subtracts busy blocks, applies open hours and buffers, then returns the time windows where everyone is free. The Nylas POST /v3/calendars/availability endpoint does this in a single request across all participants and returns the open slots for the whole group in one response.
The endpoint takes a participants array, a start_time and end_time window, a duration_minutes for the meeting length, and an interval_minutes that controls slot spacing. The availability_method field inside availability_rules accepts three values: collective for “everyone must be free”, max-fairness for round-robin load balancing, and max-availability to maximize bookable slots. A buffer of 15 minutes before and after each meeting keeps back-to-back bookings from colliding.
The request below computes overlapping free windows for two people. Use it before you render slots so the page only shows times that actually work. The round_to field snaps each slot to a clean boundary, so a window starting at 9:05 a.m. rounds to 9:15 a.m. when round_to is 15.
curl --request POST \ --url 'https://api.us.nylas.com/v3/calendars/availability' \ --header 'Authorization: Bearer <NYLAS_API_KEY>' \ --header 'Content-Type: application/json' \ --data '{ "participants": [ { "email": "[email protected]", "calendar_ids": ["primary"] }, { "email": "[email protected]", "calendar_ids": ["primary"] } ], "start_time": 1709643600, "end_time": 1709665200, "duration_minutes": 30, "interval_minutes": 30, "round_to": 15, "availability_rules": { "availability_method": "collective", "buffer": { "before": 15, "after": 15 } } }'How do booking pages and double-booking prevention work?
Section titled “How do booking pages and double-booking prevention work?”A booking page is the user-facing slot picker; double-booking prevention is the re-check that runs when someone clicks confirm. The Nylas Scheduler ties them together through a Configuration object created with POST /v3/grants/{grant_id}/scheduling/configurations, which defines who hosts, how long the meeting runs, and the rules that gate availability for that page.
The flow is two-phase, and the second phase is what saves you. First the page calls GET /v3/scheduling/availability for the Configuration and renders open slots. Then POST /v3/scheduling/bookings re-validates the chosen slot at confirmation time, so a window that filled during the 30 seconds a visitor hesitated gets rejected before any event is written. That re-check closes most of the race-condition gap automatically. Organizers can later confirm or cancel a pending booking with PUT /v3/scheduling/bookings/{booking_id}. For the concurrency pattern in full, including handling two simultaneous confirmations, see prevent double-booking.
curl --request POST \ --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/scheduling/configurations' \ --header 'Authorization: Bearer <NYLAS_API_KEY>' \ --header 'Content-Type: application/json' \ --data '{ "participants": [ { "email": "[email protected]", "is_organizer": true } ], "availability": { "duration_minutes": 30 }, "event_booking": { "title": "Intro call" } }'How is conferencing added to a booking?
Section titled “How is conferencing added to a booking?”Conferencing is added to a booking by attaching a conferencing object inside the event_booking block of the Scheduler Configuration, so every confirmed meeting auto-generates a video link without a separate API call. Set provider to a value like Zoom Meeting, then pass an autocreate block with a conf_grant_id to wire it up.
Once that’s in place, the booking step creates the meeting URL and writes it onto the event for every confirmed slot, with zero extra calls. The nested conf_settings.settings object passes provider-specific options straight through, so a Zoom meeting can set waiting_room, join_before_host, and auto_recording at booking time. One caveat worth flagging: Zoom requires granular OAuth scopes on your own Zoom app, specifically meeting:write:meeting to create the link, per the Zoom OAuth scopes documentation. Because conferencing lives on the Configuration, you set it once per booking type rather than per visitor, which keeps the booking page itself stateless. To wire conferencing onto plain calendar events instead, see add conferencing to events.
What are the advantages of a scheduling API versus building your own?
Section titled “What are the advantages of a scheduling API versus building your own?”The advantage is time and correctness: a scheduling API ships availability math, timezone handling, double-booking checks, and conferencing on day one, instead of the several months a homegrown booking engine takes to reach the same reliability. You write 3 API calls rather than maintaining a scheduling system across every provider you support.
The build-it-yourself path looks cheap until you hit the long tail. You own the Free/Busy merge across providers, daylight-saving edge cases, buffer logic, the confirmation race condition, and link generation for each video provider separately. The table below maps each job to what it costs in each approach.
| Job | Build your own | Nylas Scheduler API |
|---|---|---|
| Availability across attendees | Merge Free/Busy yourself per provider | POST /v3/calendars/availability, one call |
| Bookable slot rules | Write open-hours and buffer math | Defined on the Configuration object |
| Double-booking prevention | Re-check Free/Busy before every write | Re-validated inside POST /v3/scheduling/bookings |
| Conferencing links | Integrate each video provider separately | conferencing block, auto-created on booking |
| Provider coverage | Per-provider integration each time | Google, Microsoft, iCloud, Exchange through 1 grant |
Here’s the honest tradeoff: if your slot rules are so unusual that a Configuration can’t express them, raw event CRUD plus POST /v3/grants/{grant_id}/calendars/free-busy keeps full control in your code, at the cost of writing the booking flow yourself. For that comparison in depth, see scheduling API vs calendar API.
How do I add scheduling to a SaaS product without building from scratch?
Section titled “How do I add scheduling to a SaaS product without building from scratch?”Embed a prebuilt scheduling page or call the Scheduler endpoints directly, and skip the booking engine entirely. The fastest route is the Nylas Scheduler embeddable UI, which renders the slot picker, captures the booking, and writes the event with no availability code on your side. Most teams ship a working “book a meeting” flow in under 1 day this way.
You have two integration depths. For a drop-in widget that handles rendering and confirmation, embed the hosted page and point it at a Configuration ID. For a fully custom front end, call GET /v3/scheduling/availability to fetch slots and POST /v3/scheduling/bookings to confirm, then style the UI however you like. Both paths reuse the same Configuration, so you can start embedded and move to the API later without redoing the backend. To get the widget on a page right now, see embed a scheduling page.
What’s next
Section titled “What’s next”- Embed a scheduling page to drop a prebuilt booking flow into your app
- Scheduling API vs calendar API to pick the right layer for your integration
- Prevent double-booking for the race-condition pattern at confirmation time
- Getting started with Nylas to create a project, connector, and your first grant