diff --git a/src/main/kotlin/com/nylas/NylasClient.kt b/src/main/kotlin/com/nylas/NylasClient.kt
index 1a3e0d72..ce770e9e 100644
--- a/src/main/kotlin/com/nylas/NylasClient.kt
+++ b/src/main/kotlin/com/nylas/NylasClient.kt
@@ -151,6 +151,12 @@ open class NylasClient(
    */
   open fun contacts(): Contacts = Contacts(this)
 
+  /**
+   * Access the Scheduler API
+   * @return The Scheduler API
+   */
+  fun scheduler(): Scheduler = Scheduler(this)
+
   /**
    * Get a URL builder instance for the Nylas API.
    */
diff --git a/src/main/kotlin/com/nylas/models/AvailabilityMethod.kt b/src/main/kotlin/com/nylas/models/AvailabilityMethod.kt
index f0283a0c..82b17e51 100644
--- a/src/main/kotlin/com/nylas/models/AvailabilityMethod.kt
+++ b/src/main/kotlin/com/nylas/models/AvailabilityMethod.kt
@@ -11,4 +11,7 @@ enum class AvailabilityMethod {
 
   @Json(name = "max-availability")
   MAX_AVAILABILITY,
+
+  @Json(name = "collective")
+  COLLECTIVE,
 }
diff --git a/src/main/kotlin/com/nylas/models/AvailabilityRules.kt b/src/main/kotlin/com/nylas/models/AvailabilityRules.kt
index 4b3919d1..1f4b2c66 100644
--- a/src/main/kotlin/com/nylas/models/AvailabilityRules.kt
+++ b/src/main/kotlin/com/nylas/models/AvailabilityRules.kt
@@ -14,7 +14,7 @@ data class AvailabilityRules(
   /**
    * The buffer to add to the start and end of a meeting.
    */
-  @Json(name = "meeting_buffer")
+  @Json(name = "buffer")
   val buffer: MeetingBuffer? = null,
   /**
    * A default set of open hours to apply to all participants.
@@ -27,8 +27,8 @@ data class AvailabilityRules(
    * The ID on events that Nylas considers when calculating the order of round-robin participants.
    * This is used for both max-fairness and max-availability methods.
    */
-  @Json(name = "round_robin_event_id")
-  val roundRobinEventId: String? = null,
+  @Json(name = "round_robin_group_id")
+  val roundRobinGroupId: String? = null,
 ) {
   /**
    * A builder for creating a [AvailabilityRules].
@@ -37,7 +37,7 @@ data class AvailabilityRules(
     private var availabilityMethod: AvailabilityMethod? = null
     private var buffer: MeetingBuffer? = null
     private var defaultOpenHours: List<OpenHours>? = null
-    private var roundRobinEventId: String? = null
+    private var roundRobinGroupId: String? = null
 
     /**
      * Set the method used to determine availability for a meeting.
@@ -65,10 +65,10 @@ data class AvailabilityRules(
     /**
      * Set the ID on events that Nylas considers when calculating the order of round-robin participants.
      * This is used for both max-fairness and max-availability methods.
-     * @param roundRobinEventId The ID on events that Nylas considers when calculating the order of round-robin participants.
+     * @param roundRobinGroupId The ID on events that Nylas considers when calculating the order of round-robin participants.
      * @return The builder.
      */
-    fun roundRobinEventId(roundRobinEventId: String) = apply { this.roundRobinEventId = roundRobinEventId }
+    fun roundRobinGroupId(roundRobinGroupId: String) = apply { this.roundRobinGroupId = roundRobinGroupId }
 
     /**
      * Build the [AvailabilityRules] object.
@@ -78,7 +78,7 @@ data class AvailabilityRules(
       availabilityMethod = availabilityMethod,
       buffer = buffer,
       defaultOpenHours = defaultOpenHours,
-      roundRobinEventId = roundRobinEventId,
+      roundRobinGroupId = roundRobinGroupId,
     )
   }
 }
diff --git a/src/main/kotlin/com/nylas/models/BookingGuest.kt b/src/main/kotlin/com/nylas/models/BookingGuest.kt
new file mode 100644
index 00000000..5502a298
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/BookingGuest.kt
@@ -0,0 +1,19 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of a booking guest.
+ */
+data class BookingGuest(
+  /**
+   * The email address of the guest.
+   */
+  @Json(name = "email")
+  val email: String,
+  /**
+   * The name of the guest.
+   */
+  @Json(name = "name")
+  val name: String? = null,
+)
diff --git a/src/main/kotlin/com/nylas/models/BookingOrganizer.kt b/src/main/kotlin/com/nylas/models/BookingOrganizer.kt
new file mode 100644
index 00000000..4568aff5
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/BookingOrganizer.kt
@@ -0,0 +1,19 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of a booking organizer.
+ */
+data class BookingOrganizer(
+  /**
+   * The email address of the participant designated as the organizer of the event.
+   */
+  @Json(name = "email")
+  val email: String,
+  /**
+   * The name of the participant designated as the organizer of the event.
+   */
+  @Json(name = "name")
+  val name: String? = null,
+)
diff --git a/src/main/kotlin/com/nylas/models/BookingReminder.kt b/src/main/kotlin/com/nylas/models/BookingReminder.kt
new file mode 100644
index 00000000..842a16d4
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/BookingReminder.kt
@@ -0,0 +1,29 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of a booking reminder.
+ */
+data class BookingReminder(
+  /**
+   * The reminder type.
+   */
+  @Json(name = "type")
+  val type: String,
+  /**
+   * The number of minutes before the event to send the reminder.
+   */
+  @Json(name = "minutes_before_event")
+  val minutesBeforeEvent: Int,
+  /**
+   * The recipient of the reminder.
+   */
+  @Json(name = "recipient")
+  val recipient: String? = null,
+  /**
+   * The subject of the email reminder.
+   */
+  @Json(name = "email_subject")
+  val emailSubject: String? = null,
+)
diff --git a/src/main/kotlin/com/nylas/models/BookingStatus.kt b/src/main/kotlin/com/nylas/models/BookingStatus.kt
new file mode 100644
index 00000000..c140c163
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/BookingStatus.kt
@@ -0,0 +1,17 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Enum for booking statuses.
+ */
+enum class BookingStatus {
+  @Json(name = "pending")
+  PENDING,
+
+  @Json(name = "booked")
+  BOOKED,
+
+  @Json(name = "cancelled")
+  CANCELLED,
+}
diff --git a/src/main/kotlin/com/nylas/models/BookingType.kt b/src/main/kotlin/com/nylas/models/BookingType.kt
new file mode 100644
index 00000000..4a40ef4f
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/BookingType.kt
@@ -0,0 +1,14 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Enum for booking types.
+ */
+enum class BookingType {
+  @Json(name = "booking")
+  BOOKING,
+
+  @Json(name = "organizer-confirmation")
+  ORGANIZER_CONFIRMATION,
+}
diff --git a/src/main/kotlin/com/nylas/models/ConfigurationAvailability.kt b/src/main/kotlin/com/nylas/models/ConfigurationAvailability.kt
new file mode 100644
index 00000000..9c4d202e
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/ConfigurationAvailability.kt
@@ -0,0 +1,75 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of availability settings.
+ */
+data class ConfigurationAvailability(
+  /**
+   * The total number of minutes the event should last.
+   */
+  @Json(name = "duration_minutes")
+  val durationMinutes: Int? = null,
+  /**
+   * The interval between meetings in minutes.
+   */
+  @Json(name = "interval_minutes")
+  val intervalMinutes: Int? = null,
+  /**
+   * Nylas rounds each time slot to the nearest multiple of this number of minutes.
+   */
+  @Json(name = "round_to")
+  val roundTo: Int? = null,
+  /**
+   * Availability rules for scheduling configuration.
+   */
+  @Json(name = "availability_rules")
+  val availabilityRules: AvailabilityRules? = null,
+) {
+  class Builder {
+    private var durationMinutes: Int? = null
+    private var intervalMinutes: Int? = null
+    private var roundTo: Int? = null
+    private var availabilityRules: AvailabilityRules? = null
+
+    /**
+     * Set the duration of the event in minutes.
+     * @param durationMinutes The duration of the event in minutes.
+     * @return The builder.
+     */
+    fun durationMinutes(durationMinutes: Int?) = apply { this.durationMinutes = durationMinutes }
+
+    /**
+     * Set the interval between meetings in minutes.
+     * @param intervalMinutes The interval between meetings in minutes.
+     * @return The builder.
+     */
+    fun intervalMinutes(intervalMinutes: Int?) = apply { this.intervalMinutes = intervalMinutes }
+
+    /**
+     * Set Nylas rounds each time slot to the nearest multiple of this number of minutes.
+     * @param roundTo Nylas rounds each time slot to the nearest multiple of this number of minutes.
+     * @return The builder.
+     */
+    fun roundTo(roundTo: Int?) = apply { this.roundTo = roundTo }
+
+    /**
+     * Set availability rules for scheduling configuration.
+     * @param availabilityRules Availability rules for scheduling configuration.
+     * @return The builder.
+     */
+    fun availabilityRules(availabilityRules: AvailabilityRules?) = apply { this.availabilityRules = availabilityRules }
+
+    /**
+     * Build the [ConfigurationAvailability].
+     * @return The [ConfigurationAvailability].
+     */
+    fun build() = ConfigurationAvailability(
+      durationMinutes,
+      intervalMinutes,
+      roundTo,
+      availabilityRules,
+    )
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/ConfigurationAvailabilityParticipant.kt b/src/main/kotlin/com/nylas/models/ConfigurationAvailabilityParticipant.kt
new file mode 100644
index 00000000..b2297da6
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/ConfigurationAvailabilityParticipant.kt
@@ -0,0 +1,52 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of a participant in a booking.
+ */
+
+data class ConfigurationAvailabilityParticipant(
+  /**
+   * @param calendarIds The calendar IDs that the event is created in.
+   */
+  @Json(name = "calendar_ids")
+  val calendarIds: List<String>? = emptyList(),
+  /**
+   * Open hours for this participant. The endpoint searches for free time slots during these open hours.
+   */
+  @Json(name = "open_hours")
+  val openHours: List<OpenHours>? = null,
+) {
+  /**
+   * Builder for [ConfigurationAvailabilityParticipant].
+   */
+  class Builder {
+    private var calendarIds: List<String>? = null
+    private var openHours: List<OpenHours>? = null
+
+    /**
+     * Set the calendar IDs for this participant.
+     * @param calendarIds Calendar IDs for this participant.
+     * @return The builder.
+     */
+    fun calendarIds(calendarIds: List<String>) = apply { this.calendarIds = calendarIds }
+
+    /**
+     * Set the open hours for this participant.
+     * @param openHours Open hours for this participant.
+     * @return The builder.
+     */
+    fun openHours(openHours: List<OpenHours>) = apply { this.openHours = openHours }
+
+    /**
+     * Set the open hours for this participant.
+     * @param openHours Open hours for this participant.
+     * @return The builder.
+     */
+    fun build() = ConfigurationAvailabilityParticipant(
+      calendarIds,
+      openHours,
+    )
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/ConfigurationBookingParticipant.kt b/src/main/kotlin/com/nylas/models/ConfigurationBookingParticipant.kt
new file mode 100644
index 00000000..5946a2cc
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/ConfigurationBookingParticipant.kt
@@ -0,0 +1,34 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of a participant in a booking.
+ */
+data class ConfigurationBookingParticipant(
+  /**
+   * The calendar ID that the event is created in.
+   */
+  @Json(name = "calendar_id")
+  val calendarId: String? = null,
+) {
+  /**
+   * Builder for [ConfigurationBookingParticipant].
+   */
+  class Builder {
+    private var calendarId: String? = null
+
+    /**
+     * Set the calendar ID for this participant.
+     * @param calendarId The calendar ID for this participant.
+     * @return The builder.
+     */
+    fun calendarId(calendarId: String?) = apply { this.calendarId = calendarId }
+
+    /**
+     * Builds a [ConfigurationBookingParticipant] instance.
+     * @return The [ConfigurationBookingParticipant] instance.
+     */
+    fun build() = ConfigurationBookingParticipant(calendarId)
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/ConfigurationEventBooking.kt b/src/main/kotlin/com/nylas/models/ConfigurationEventBooking.kt
new file mode 100644
index 00000000..4acec054
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/ConfigurationEventBooking.kt
@@ -0,0 +1,148 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of an event booking.
+ */
+data class ConfigurationEventBooking(
+  /**
+   * The title of the event.
+   */
+  @Json(name = "title")
+  val title: String? = null,
+  /**
+   * The description of the event.
+   */
+  @Json(name = "description")
+  val description: String? = null,
+  /**
+   * The location of the event.
+   */
+  @Json(name = "location")
+  val location: String? = null,
+  /**
+   * The timezone for displaying times in confirmation email messages and reminders.
+   */
+  @Json(name = "timezone")
+  val timezone: String? = null,
+  /**
+   * The type of booking.
+   */
+  @Json(name = "booking_type")
+  val bookingType: BookingType? = null,
+  /**
+   * Conference details for the event.
+   */
+  @Json(name = "conferencing")
+  val conferencing: Conferencing? = null,
+  /**
+   * Whether Nylas sends email messages when an event is booked, cancelled, or rescheduled.
+   */
+  @Json(name = "disable_emails")
+  val disableEmails: Boolean? = null,
+  /**
+   * The list of reminders to send to participants before the event starts.
+   */
+  @Json(name = "reminders")
+  val reminders: List<BookingReminder>? = null,
+  /**
+   * Whether to hide participants from the event booking.
+   */
+  @Json(name = "hide_participants")
+  val hideParticipants: Boolean? = null,
+) {
+  /**
+   * Builder for [ConfigurationEventBooking].
+   */
+  class Builder {
+    private var title: String? = null
+    private var description: String? = null
+    private var location: String? = null
+    private var timezone: String? = null
+    private var bookingType: BookingType? = null
+    private var conferencing: Conferencing? = null
+    private var disableEmails: Boolean? = null
+    private var reminders: List<BookingReminder>? = null
+    private var hideParticipants: Boolean? = null
+
+    /**
+     * Set the title of the event.
+     * @param title The title of the event.
+     * @return The builder.
+     */
+    fun title(title: String?) = apply { this.title = title }
+
+    /**
+     * Sets the description of the event.
+     * @param description The description of the event.
+     * @return The builder.
+     */
+    fun description(description: String?) = apply { this.description = description }
+
+    /**
+     * Sets the location of the event.
+     * @param location The location of the event.
+     * @return The builder.
+     */
+    fun location(location: String?) = apply { this.location = location }
+
+    /**
+     * Sets the timezone for displaying times in confirmation email messages and reminders.
+     * @param timezone The timezone for displaying times in confirmation email messages and reminders.
+     * @return The builder.
+     */
+    fun timezone(timezone: String?) = apply { this.timezone = timezone }
+
+    /**
+     * Sets the type of booking.
+     * @param bookingType The type of booking.
+     * @return The builder.
+     */
+    fun bookingType(bookingType: BookingType?) = apply { this.bookingType = bookingType }
+
+    /**
+     * Sets the conference details for the event.
+     * @param conferencing Conference details for the event.
+     * @return The builder.
+     */
+    fun conferencing(conferencing: Conferencing?) = apply { this.conferencing = conferencing }
+
+    /**
+     * Sets whether Nylas sends email messages when an event is booked, cancelled, or rescheduled.
+     * @param disableEmails Whether Nylas sends email messages when an event is booked, cancelled, or rescheduled.
+     * @return The builder.
+     */
+    fun disableEmails(disableEmails: Boolean?) = apply { this.disableEmails = disableEmails }
+
+    /**
+     * Sets the list of reminders to send to participants before the event starts.
+     * @param reminders The list of reminders to send to participants before the event starts.
+     * @return
+     */
+    fun reminders(reminders: List<BookingReminder>?) = apply { this.reminders = reminders }
+
+    /**
+     * Sets whether to hide participants from the event booking.
+     * @param hideParticipants Whether to hide participants from the event booking.
+     * @return The builder.
+     */
+    fun hideParticipants(hideParticipants: Boolean?) = apply { this.hideParticipants = hideParticipants }
+
+    /**
+     * Builds an [ConfigurationEventBooking] instance.
+     * @return The [ConfigurationEventBooking] instance.
+     */
+    fun build() = ConfigurationEventBooking(
+      title,
+      description,
+      location,
+      timezone,
+      bookingType,
+      conferencing,
+      disableEmails,
+      reminders,
+      hideParticipants,
+    )
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/ConfigurationParticipant.kt b/src/main/kotlin/com/nylas/models/ConfigurationParticipant.kt
new file mode 100644
index 00000000..36afd68b
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/ConfigurationParticipant.kt
@@ -0,0 +1,100 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of a participant in a scheduled event.
+ * @property email Email address of the participant.
+ * @property name Name of the participant.
+ * @property role Role of the participant.
+ * @property availability Availability data for the participant.
+ * @property booking Booking data for the participant.
+ * @property timezone Timezone of the participant.
+ */
+data class ConfigurationParticipant(
+  /**
+   * Email address of the participant.
+   */
+  @Json(name = "email")
+  val email: String,
+  /**
+   * Name of the participant.
+   */
+  @Json(name = "name")
+  val name: String? = null,
+  /**
+   * If true, the participant is the organizer of the event.
+   */
+  @Json(name = "is_organizer")
+  val isOrganizer: Boolean? = null,
+  /**
+   * Availability data for the participant.
+   */
+  @Json(name = "availability")
+  val availability: ConfigurationAvailabilityParticipant? = null,
+  /**
+   * Booking data for the participant.
+   */
+  @Json(name = "booking")
+  val booking: ConfigurationBookingParticipant? = null,
+  /**
+   * Timezone of the participant.
+   */
+  @Json(name = "timezone")
+  val timezone: String? = null,
+) {
+  /**
+   * A builder for creating a [ConfigurationParticipant].
+   * @param email Email address of the participant.
+   */
+  data class Builder(
+    private val email: String,
+  ) {
+    private var name: String? = null
+    private var isOrganizer: Boolean? = null
+    private var availability: ConfigurationAvailabilityParticipant? = null
+    private var booking: ConfigurationBookingParticipant? = null
+    private var timezone: String? = null
+
+    /**
+     * Set the name of the participant.
+     * @param name Name of the participant.
+     * @return The builder.
+     */
+    fun name(name: String) = apply { this.name = name }
+
+    /**
+     * Set if the participant is the organizer of the event.
+     * @param isOrganizer If true, the participant is the organizer of the event.
+     * @return The builder.
+     */
+    fun isOrganizer(isOrganizer: Boolean) = apply { this.isOrganizer = isOrganizer }
+
+    /**
+     * Set the availability data for the participant.
+     * @param availability Availability data for the participant.
+     * @return The builder.
+     */
+    fun availability(availability: ConfigurationAvailabilityParticipant) = apply { this.availability = availability }
+
+    /**
+     * Set the booking data for the participant.
+     * @param booking Booking data for the participant.
+     * @return The builder.
+     */
+    fun booking(booking: ConfigurationBookingParticipant) = apply { this.booking = booking }
+
+    /**
+     * Set the timezone of the participant.
+     * @param timezone Timezone of the participant.
+     * @return The builder.
+     */
+    fun timezone(timezone: String) = apply { this.timezone = timezone }
+
+    /**
+     * Build the [ConfigurationParticipant].
+     * @return The [ConfigurationParticipant]
+     */
+    fun build() = ConfigurationParticipant(email, name, isOrganizer, availability, booking, timezone)
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/ConfigurationSchedulerSettings.kt b/src/main/kotlin/com/nylas/models/ConfigurationSchedulerSettings.kt
new file mode 100644
index 00000000..c67bb771
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/ConfigurationSchedulerSettings.kt
@@ -0,0 +1,333 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of scheduler settings.
+ */
+data class ConfigurationSchedulerSettings(
+  /**
+   * Definitions for additional fields to be displayed in the Scheduler UI.
+   */
+  @Json(name = "additional_fields")
+  val additionalFields: Map<String, AdditionalField>? = null,
+  /**
+   * Number of days in the future that Scheduler is available for scheduling events.
+   */
+  @Json(name = "available_days_in_future")
+  val availableDaysInFuture: Int? = null,
+  /**
+   * Minimum number of minutes in the future that a user can make a new booking.
+   */
+  @Json(name = "min_booking_notice")
+  val minBookingNotice: Int? = null,
+  /**
+   * Minimum number of minutes before a booking can be cancelled.
+   */
+  @Json(name = "min_cancellation_notice")
+  val minCancellationNotice: Int? = null,
+  /**
+   * A message about the cancellation policy to display when booking an event.
+   */
+  @Json(name = "cancellation_policy")
+  val cancellationPolicy: String? = null,
+  /**
+   * The URL used to reschedule bookings.
+   */
+  @Json(name = "rescheduling_url")
+  val reschedulingUrl: String? = null,
+  /**
+   * The URL used to cancel bookings.
+   */
+  @Json(name = "cancellation_url")
+  val cancellationUrl: String? = null,
+  /**
+   * The URL used to confirm or cancel pending bookings.
+   */
+  @Json(name = "organizer_confirmation_url")
+  val organizerConfirmationUrl: String? = null,
+  /**
+   * The custom URL to redirect to once the booking is confirmed.
+   */
+  @Json(name = "confirmation_redirect_url")
+  val confirmationRedirectUrl: String? = null,
+  /**
+   * Whether the option to reschedule an event is hidden in booking confirmations and notifications.
+   */
+  @Json(name = "hide_rescheduling_options")
+  val hideReschedulingOptions: Boolean? = null,
+  /**
+   * Whether the option to cancel an event is hidden in booking confirmations and notifications.
+   */
+  @Json(name = "hide_cancellation_options")
+  val hideCancellationOptions: Boolean? = null,
+  /**
+   * Whether to hide the additional guests field on the scheduling page.
+   */
+  @Json(name = "hide_additional_guests")
+  val hideAdditionalGuests: Boolean? = null,
+  /**
+   * Configurable settings for booking emails.
+   */
+  @Json(name = "email_template")
+  val emailTemplate: EmailTemplate? = null,
+) {
+  class Builder {
+    private var additionalFields: Map<String, AdditionalField>? = null
+    private var availableDaysInFuture: Int? = null
+    private var minBookingNotice: Int? = null
+    private var minCancellationNotice: Int? = null
+    private var cancellationPolicy: String? = null
+    private var reschedulingUrl: String? = null
+    private var cancellationUrl: String? = null
+    private var organizerConfirmationUrl: String? = null
+    private var confirmationRedirectUrl: String? = null
+    private var hideReschedulingOptions: Boolean? = null
+    private var hideCancellationOptions: Boolean? = null
+    private var hideAdditionalGuests: Boolean? = null
+    private var emailTemplate: EmailTemplate? = null
+
+    /**
+     * Set the definitions for additional fields to be displayed in the Scheduler UI.
+     *
+     * @param additionalFields Definitions for additional fields to be displayed in the Scheduler UI.
+     * @return The builder.
+     */
+    fun additionalFields(additionalFields: Map<String, AdditionalField>) = apply { this.additionalFields = additionalFields }
+
+    /**
+     * Set the number of days in the future that Scheduler is available for scheduling events.
+     *
+     * @param availableDaysInFuture Number of days in the future that Scheduler is available for scheduling events.
+     * @return The builder.
+     */
+    fun availableDaysInFuture(availableDaysInFuture: Int) = apply { this.availableDaysInFuture = availableDaysInFuture }
+
+    /**
+     * Set the minimum number of minutes in the future that a user can make a new booking.
+     *
+     * @param minBookingNotice Minimum number of minutes in the future that a user can make a new booking.
+     * @return The builder.
+     */
+    fun minBookingNotice(minBookingNotice: Int) = apply { this.minBookingNotice = minBookingNotice }
+
+    /**
+     * Set the minimum number of minutes before a booking can be cancelled.
+     *
+     * @param minCancellationNotice Minimum number of minutes before a booking can be cancelled.
+     * @return The builder.
+     */
+    fun minCancellationNotice(minCancellationNotice: Int) = apply { this.minCancellationNotice = minCancellationNotice }
+
+    /**
+     * Set a message about the cancellation policy to display when booking an event.
+     *
+     * @param cancellationPolicy A message about the cancellation policy to display when booking an event.
+     * @return The builder.
+     */
+    fun cancellationPolicy(cancellationPolicy: String) = apply { this.cancellationPolicy = cancellationPolicy }
+
+    /**
+     * Set the URL used to reschedule bookings.
+     *
+     * @param reschedulingUrl The URL used to reschedule bookings.
+     * @return The builder.
+     */
+    fun reschedulingUrl(reschedulingUrl: String) = apply { this.reschedulingUrl = reschedulingUrl }
+
+    /**
+     * Set the URL used to cancel bookings.
+     *
+     * @param cancellationUrl The URL used to cancel bookings.
+     * @return The builder.
+     */
+    fun cancellationUrl(cancellationUrl: String) = apply { this.cancellationUrl = cancellationUrl }
+
+    /**
+     * Set the URL used to confirm or cancel pending bookings.
+     *
+     * @param organizerConfirmationUrl The URL used to confirm or cancel pending bookings.
+     * @return The builder.
+     */
+    fun organizerConfirmationUrl(organizerConfirmationUrl: String) = apply { this.organizerConfirmationUrl = organizerConfirmationUrl }
+
+    /**
+     * Set the custom URL to redirect to once the booking is confirmed.
+     *
+     * @param confirmationRedirectUrl The custom URL to redirect to once the booking is confirmed.
+     * @return The builder.
+     */
+    fun confirmationRedirectUrl(confirmationRedirectUrl: String) = apply { this.confirmationRedirectUrl = confirmationRedirectUrl }
+
+    /**
+     * Set whether the option to reschedule an event is hidden in booking confirmations and notifications.
+     *
+     * @param hideReschedulingOptions Whether the option to reschedule an event is hidden in booking confirmations and notifications.
+     * @return The builder.
+     */
+    fun hideReschedulingOptions(hideReschedulingOptions: Boolean) = apply { this.hideReschedulingOptions = hideReschedulingOptions }
+
+    /**
+     * Set whether the option to cancel an event is hidden in booking confirmations and notifications.
+     *
+     * @param hideCancellationOptions Whether the option to cancel an event is hidden in booking confirmations and notifications.
+     * @return The builder.
+     */
+    fun hideCancellationOptions(hideCancellationOptions: Boolean) = apply { this.hideCancellationOptions = hideCancellationOptions }
+
+    /**
+     * Set whether to hide the additional guests field on the scheduling page.
+     *
+     * @param hideAdditionalGuests Whether to hide the additional guests field on the scheduling page.
+     * @return The builder.
+     */
+    fun hideAdditionalGuests(hideAdditionalGuests: Boolean) = apply { this.hideAdditionalGuests = hideAdditionalGuests }
+
+    /**
+     * Set the configurable settings for booking emails.
+     *
+     * @param emailTemplate Configurable settings for booking emails.
+     * @return The builder.
+     */
+    fun emailTemplate(emailTemplate: EmailTemplate) = apply { this.emailTemplate = emailTemplate }
+
+    /**
+     * Build the [ConfigurationSchedulerSettings].
+     *
+     * @return The [ConfigurationSchedulerSettings]
+     */
+    fun build() = ConfigurationSchedulerSettings(
+      additionalFields,
+      availableDaysInFuture,
+      minBookingNotice,
+      minCancellationNotice,
+      cancellationPolicy,
+      reschedulingUrl,
+      cancellationUrl,
+      organizerConfirmationUrl,
+      confirmationRedirectUrl,
+      hideReschedulingOptions,
+      hideCancellationOptions,
+      hideAdditionalGuests,
+      emailTemplate,
+    )
+  }
+}
+
+/**
+ * Class representation of an additional field.
+ */
+data class AdditionalField(
+  /**
+   * The text label to be displayed in the Scheduler UI.
+   */
+  @Json(name = "label")
+  val label: String,
+  /**
+   * The field type.
+   * Supported values are text, multi_line_text, email, phone_number, dropdown, date, checkbox, and radio_button.
+   */
+  @Json(name = "type")
+  val type: AdditionalFieldType,
+  /**
+   * Whether the field is required to be filled out by the guest when booking an event.
+   */
+  @Json(name = "required")
+  val required: Boolean,
+  /**
+   * A regular expression pattern that the value of the field must match.
+   */
+  @Json(name = "pattern")
+  val pattern: String? = null,
+  /**
+   * The order in which the field will be displayed in the Scheduler UI.
+   * Fields with lower order values will be displayed first.
+   */
+  @Json(name = "order")
+  val order: Int? = null,
+  /**
+   * A list of options for the dropdown or radio_button types.
+   * This field is required for the dropdown and radio_button types.
+   */
+  @Json(name = "options")
+  val options: AdditonalFieldOptionsType? = null,
+)
+
+/**
+ * Class representation of an email template.
+ */
+data class EmailTemplate(
+  /**
+   * Configurable settings specifically for booking confirmed emails.
+   */
+  @Json(name = "booking_confirmed")
+  val bookingConfirmed: BookingConfirmedTemplate? = null,
+)
+
+/**
+ * Class representation of booking confirmed template settings.
+ */
+data class BookingConfirmedTemplate(
+  /**
+   * The title to replace the default 'Booking Confirmed' title.
+   */
+  @Json(name = "title")
+  val title: String? = null,
+  /**
+   * The additional body to be appended after the default body.
+   */
+  @Json(name = "body")
+  val body: String? = null,
+)
+
+/**
+ * Enum for additional field types.
+ */
+enum class AdditionalFieldType {
+  @Json(name = "text")
+  TEXT,
+
+  @Json(name = "multi_line_text")
+  MULTI_LINE_TEXT,
+
+  @Json(name = "email")
+  EMAIL,
+
+  @Json(name = "phone_number")
+  PHONE_NUMBER,
+
+  @Json(name = "dropdown")
+  DROPDOWN,
+
+  @Json(name = "date")
+  DATE,
+
+  @Json(name = "checkbox")
+  CHECKBOX,
+
+  @Json(name = "radio_button")
+  RADIO_BUTTON,
+}
+
+/**
+ * Enum for additional field options types.
+ */
+enum class AdditonalFieldOptionsType {
+  @Json(name = "text")
+  TEXT,
+
+  @Json(name = "email")
+  EMAIL,
+
+  @Json(name = "phone_number")
+  PHONE_NUMBER,
+
+  @Json(name = "date")
+  DATE,
+
+  @Json(name = "checkbox")
+  CHECKBOX,
+
+  @Json(name = "radio_button")
+  RADIO_BUTTON,
+}
diff --git a/src/main/kotlin/com/nylas/models/ConfirmBookingQueryParams.kt b/src/main/kotlin/com/nylas/models/ConfirmBookingQueryParams.kt
new file mode 100644
index 00000000..9f7f754d
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/ConfirmBookingQueryParams.kt
@@ -0,0 +1,60 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of the query parameters for confirming a booking.
+ */
+data class ConfirmBookingQueryParams(
+  /**
+   * The ID of the Configuration object whose settings are used for calculating availability.
+   */
+  @Json(name = "configuration_id")
+  val configurationId: String? = null,
+  /**
+   * The slug of the Configuration object whose settings are used for calculating availability.
+   */
+  @Json(name = "slug")
+  val slug: String? = null,
+  /**
+   * The client ID that was used to create the Configuration object.
+   */
+  @Json(name = "client_id")
+  val clientId: String? = null,
+) : IQueryParams {
+  /**
+   * Builder for [ConfirmBookingQueryParams].
+   */
+  class Builder {
+    private var configurationId: String? = null
+    private var slug: String? = null
+    private var clientId: String? = null
+
+    /**
+     * Set the configuration ID of the booking.
+     * @param configurationId The configuration ID of the booking.
+     * @return The builder.
+     */
+    fun configurationId(configurationId: String) = apply { this.configurationId = configurationId }
+
+    /**
+     * Set the slug of the booking.
+     * @param slug The slug of the booking.
+     * @return The builder.
+     */
+    fun slug(slug: String) = apply { this.slug = slug }
+
+    /**
+     * Set the client ID of the booking.
+     * @param clientId The client ID of the booking.
+     * @return The builder.
+     */
+    fun clientId(clientId: String) = apply { this.clientId = clientId }
+
+    /**
+     * Builds a [ConfirmBookingQueryParams] instance.
+     * @return The [ConfirmBookingQueryParams] instance.
+     */
+    fun build() = ConfirmBookingQueryParams(configurationId, slug, clientId)
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/ConfirmBookingRequest.kt b/src/main/kotlin/com/nylas/models/ConfirmBookingRequest.kt
new file mode 100644
index 00000000..aa278d7f
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/ConfirmBookingRequest.kt
@@ -0,0 +1,57 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of the request body for confirming a booking.
+ */
+data class ConfirmBookingRequest(
+  @Json(name = "status")
+  val status: ConfirmBookingStatus? = null,
+  /**
+   * The salt extracted from the booking reference embedded in the organizer confirmation link.
+   */
+  @Json(name = "salt")
+  val salt: String? = null,
+  /**
+   * The reason the booking is being cancelled.
+   */
+  @Json(name = "cancellation_reason")
+  val cancellationReason: String? = null,
+) {
+  /**
+   * Builder for [ConfirmBookingRequest].
+   */
+  class Builder {
+    private var status: ConfirmBookingStatus? = null
+    private var salt: String? = null
+    private var cancellationReason: String? = null
+
+    /**
+     * Set the status of the booking.
+     * @param status The status of the booking.
+     * @return The builder.
+     */
+    fun status(status: ConfirmBookingStatus) = apply { this.status = status }
+
+    /**
+     * Set the salt of the booking.
+     * @param salt The salt of the booking.
+     * @return The builder.
+     */
+    fun salt(salt: String) = apply { this.salt = salt }
+
+    /**
+     * Set the cancellation reason of the booking.
+     * @param cancellationReason The cancellation reason of the booking.
+     * @return The builder.
+     */
+    fun cancellationReason(cancellationReason: String) = apply { this.cancellationReason = cancellationReason }
+
+    /**
+     * Builds a [ConfirmBookingRequest] instance.
+     * @return The [ConfirmBookingRequest] instance.
+     */
+    fun build() = ConfirmBookingRequest(status, salt, cancellationReason)
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/ConfirmBookingStatus.kt b/src/main/kotlin/com/nylas/models/ConfirmBookingStatus.kt
new file mode 100644
index 00000000..b8d5c937
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/ConfirmBookingStatus.kt
@@ -0,0 +1,14 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Enum for confirm booking statuses.
+ */
+enum class ConfirmBookingStatus {
+  @Json(name = "confirmed")
+  CONFIRMED,
+
+  @Json(name = "cancelled")
+  CANCELLED,
+}
diff --git a/src/main/kotlin/com/nylas/models/CreateBookingGuest.kt b/src/main/kotlin/com/nylas/models/CreateBookingGuest.kt
new file mode 100644
index 00000000..69deedc5
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/CreateBookingGuest.kt
@@ -0,0 +1,41 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of a request to create a booking guest.
+ */
+data class CreateBookingGuest(
+  /**
+   * The email address of the guest.
+   */
+  @Json(name = "email")
+  val email: String,
+  /**
+   * The name of the guest.
+   */
+  @Json(name = "name")
+  val name: String? = null,
+) {
+  /**
+   * Builder for [CreateBookingGuest].
+   */
+  data class Builder(
+    private val email: String,
+  ) {
+    private var name: String? = null
+
+    /**
+     * Set the name of the guest.
+     * @param name The name of the guest.
+     * @return The builder.
+     */
+    fun name(name: String) = apply { this.name = name }
+
+    /**
+     * Builds a [CreateBookingGuest] instance.
+     * @return The [CreateBookingGuest] instance.
+     */
+    fun build() = CreateBookingGuest(email, name)
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/CreateBookingOrganizer.kt b/src/main/kotlin/com/nylas/models/CreateBookingOrganizer.kt
new file mode 100644
index 00000000..ddf441e6
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/CreateBookingOrganizer.kt
@@ -0,0 +1,41 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representing a request to create a booking organizer.
+ */
+data class CreateBookingOrganizer(
+  /**
+   * The email address of the participant designated as the organizer of the event.
+   */
+  @Json(name = "email")
+  val email: String,
+  /**
+   * The name of the participant designated as the organizer of the event.
+   */
+  @Json(name = "name")
+  val name: String? = null,
+) {
+  /**
+   * Builder for [CreateBookingOrganizer].
+   */
+  data class Builder(
+    private val email: String,
+  ) {
+    private var name: String? = null
+
+    /**
+     * Set the name of the participant designated as the organizer of the event.
+     * @param name The name of the participant designated as the organizer of the event.
+     * @return The builder.
+     */
+    fun name(name: String) = apply { this.name = name }
+
+    /**
+     * Builds a [CreateBookingOrganizer] instance.
+     * @return The [CreateBookingOrganizer] instance.
+     */
+    fun build() = CreateBookingOrganizer(email, name)
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/CreateBookingQueryParams.kt b/src/main/kotlin/com/nylas/models/CreateBookingQueryParams.kt
new file mode 100644
index 00000000..59a9eb06
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/CreateBookingQueryParams.kt
@@ -0,0 +1,60 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of the query parameters for creating a booking.
+ */
+data class CreateBookingQueryParams(
+  /**
+   * The ID of the Configuration object whose settings are used for calculating availability.
+   */
+  @Json(name = "configuration_id")
+  val configurationId: String? = null,
+  /**
+   * The slug of the Configuration object whose settings are used for calculating availability.
+   */
+  @Json(name = "slug")
+  val slug: String? = null,
+  /**
+   * The client ID that was used to create the Configuration object.
+   */
+  @Json(name = "client_id")
+  val clientId: String? = null,
+) : IQueryParams {
+  /**
+   * Builder for [CreateBookingQueryParams].
+   */
+  class Builder {
+    private var configurationId: String? = null
+    private var slug: String? = null
+    private var clientId: String? = null
+
+    /**
+     * Sets the ID of the Configuration object whose settings are used for calculating availability.
+     * @param configurationId The ID of the Configuration object whose settings are used for calculating availability.
+     * @return The builder.
+     */
+    fun configurationId(configurationId: String) = apply { this.configurationId = configurationId }
+
+    /**
+     * Sets the slug of the Configuration object whose settings are used for calculating availability.
+     * @param slug The slug of the Configuration object whose settings are used for calculating availability.
+     * @return The builder.
+     */
+    fun slug(slug: String) = apply { this.slug = slug }
+
+    /**
+     * Sets the client ID that was used to create the Configuration object.
+     * @param clientId The client ID that was used to create the Configuration object.
+     * @return The builder.
+     */
+    fun clientId(clientId: String) = apply { this.clientId = clientId }
+
+    /**
+     * Builds a [CreateBookingQueryParams] instance.
+     * @return The [CreateBookingQueryParams] instance.
+     */
+    fun build() = CreateBookingQueryParams(configurationId, slug, clientId)
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/CreateBookingReminder.kt b/src/main/kotlin/com/nylas/models/CreateBookingReminder.kt
new file mode 100644
index 00000000..40f2d3a9
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/CreateBookingReminder.kt
@@ -0,0 +1,60 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of a request to create a booking reminder.
+ */
+data class CreateBookingReminder(
+  /**
+   * The reminder type.
+   */
+  @Json(name = "type")
+  val type: String,
+  /**
+   * The number of minutes before the event to send the reminder.
+   */
+  @Json(name = "minutes_before_event")
+  val minutesBeforeEvent: Int,
+  /**
+   * The recipient of the reminder.
+   */
+  @Json(name = "recipient")
+  val recipient: String? = null,
+  /**
+   * The subject of the email reminder.
+   */
+  @Json(name = "email_subject")
+  val emailSubject: String? = null,
+) {
+  /**
+   * Builder for [CreateBookingReminder].
+   */
+  data class Builder(
+    private val type: String,
+    private val minutesBeforeEvent: Int,
+  ) {
+    private var recipient: String? = null
+    private var emailSubject: String? = null
+
+    /**
+     * Set the recipient of the reminder.
+     * @param recipient The recipient of the reminder.
+     * @return The builder.
+     */
+    fun recipient(recipient: String) = apply { this.recipient = recipient }
+
+    /**
+     * Set the subject of the email reminder.
+     * @param emailSubject The subject of the email reminder.
+     * @return The builder.
+     */
+    fun emailSubject(emailSubject: String) = apply { this.emailSubject = emailSubject }
+
+    /**
+     * Builds a [CreateBookingReminder] instance.
+     * @return The [CreateBookingReminder] instance.
+     */
+    fun build() = CreateBookingReminder(type, minutesBeforeEvent, recipient, emailSubject)
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/CreateBookingRequest.kt b/src/main/kotlin/com/nylas/models/CreateBookingRequest.kt
new file mode 100644
index 00000000..a3879f4a
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/CreateBookingRequest.kt
@@ -0,0 +1,127 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of a confirm booking request.
+ */
+data class CreateBookingRequest(
+  /**
+   * The event's start time, in Unix epoch format.
+   */
+  @Json(name = "start_time")
+  val startTime: String? = null,
+  /**
+   * The event's end time, in Unix epoch format.
+   */
+  @Json(name = "end_time")
+  val endTime: String? = null,
+  /**
+   * An array of objects that include a list of participant
+   * email addresses from the Configuration object to include in the booking.
+   * If not provided, Nylas includes all participants from the Configuration object.
+   */
+  @Json(name = "participants")
+  val participants: List<BookingParticipant>? = null,
+  /**
+   * Details about the guest that is creating the booking. The guest name and email are required.
+   */
+  @Json(name = "guest")
+  val guest: BookingGuest? = null,
+  /**
+   * The guest's timezone that is used in email notifications.
+   */
+  @Json(name = "timezone")
+  val timezone: String? = null,
+  /**
+   * The language of the guest's email notifications.
+   */
+  @Json(name = "email_language")
+  val emailLanguage: EmailLanguage? = null,
+  /**
+   * An array of objects that include a list of additional guest email addresses to include in the booking.
+   */
+  @Json(name = "additional_guests")
+  val additionalGuests: List<BookingGuest>? = null,
+  /**
+   * A dictionary of additional field keys mapped to the values populated by the guest in the booking form.
+   */
+  @Json(name = "additional_fields")
+  val additionalFields: Map<String, String>? = null,
+) {
+  /**
+   * Builder for [CreateBookingRequest].
+   */
+  class Builder {
+    private var startTime: String? = null
+    private var endTime: String? = null
+    private var participants: List<BookingParticipant>? = null
+    private var guest: BookingGuest? = null
+    private var timezone: String? = null
+    private var emailLanguage: EmailLanguage? = null
+    private var additionalGuests: List<BookingGuest>? = null
+    private var additionalFields: Map<String, String>? = null
+
+    /**
+     * Set the start time of the booking.
+     * @param startTime The start time of the booking.
+     * @return The builder.
+     */
+    fun startTime(startTime: String) = apply { this.startTime = startTime }
+
+    /**
+     * Set the end time of the booking.
+     * @param endTime The end time of the booking.
+     * @return The builder.
+     */
+    fun endTime(endTime: String) = apply { this.endTime = endTime }
+
+    /**
+     * Set the participants of the booking.
+     * @param participants The participants of the booking.
+     * @return The builder.
+     */
+    fun participants(participants: List<BookingParticipant>) = apply { this.participants = participants }
+
+    /**
+     * Set the guests of the booking.
+     * @param guests The guests of the booking.
+     * @return The builder.
+     */
+    fun guest(guest: BookingGuest) = apply { this.guest = guest }
+
+    /**
+     * Set the timezone of the booking.
+     * @param timezone The timezone of the booking.
+     * @return The builder.
+     */
+    fun timezone(timezone: String) = apply { this.timezone = timezone }
+
+    /**
+     * Set the email language of the booking.
+     * @param emailLanguage The email language of the booking.
+     * @return The builder.
+     */
+    fun emailLanguage(emailLanguage: EmailLanguage) = apply { this.emailLanguage = emailLanguage }
+
+    /**
+     * Set the additional guests of the booking.
+     * @param additionalGuests The additional guests of the booking.
+     * @return The builder.
+     */
+    fun additionalGuests(additionalGuests: List<BookingGuest>) = apply { this.additionalGuests = additionalGuests }
+
+    /**
+     * Set the additional fields of the booking.
+     * @param additionalFields The additional fields of the booking.
+     * @return The builder.
+     */
+    fun additionalFields(additionalFields: Map<String, String>) = apply { this.additionalFields = additionalFields }
+
+    /**
+     * Builds a [CreateBookingRequest] instance.
+     * @return The [CreateBookingRequest] instance.
+     */
+    fun build() = CreateBookingRequest(startTime, endTime, participants, guest, timezone, emailLanguage, additionalGuests, additionalFields)
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/CreateConfigurationRequest.kt b/src/main/kotlin/com/nylas/models/CreateConfigurationRequest.kt
new file mode 100644
index 00000000..763dabd8
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/CreateConfigurationRequest.kt
@@ -0,0 +1,108 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of a request to create a configuration.
+ */
+data class CreateConfigurationRequest(
+  /**
+   * List of participants included in the scheduled event.
+   */
+  @Json(name = "participants")
+  val participants: List<ConfigurationParticipant>,
+  /**
+   * Rules that determine available time slots for the event.
+   */
+  @Json(name = "availability")
+  val availability: ConfigurationAvailability,
+  /**
+   * Booking data for the event.
+   */
+  @Json(name = "event_booking")
+  val eventBooking: ConfigurationEventBooking,
+  /**
+   * Unique identifier for the Configuration object.
+   */
+  @Json(name = "slug")
+  val slug: String? = null,
+  /**
+   * If true, scheduling Availability and Bookings endpoints require a valid session ID.
+   */
+  @Json(name = "requires_session_auth")
+  val requiresSessionAuth: Boolean? = null,
+  /**
+   * Settings for the Scheduler UI.
+   */
+  @Json(name = "scheduler")
+  val scheduler: ConfigurationSchedulerSettings? = null,
+  /**
+   * Appearance settings for the Scheduler UI.
+   */
+  @Json(name = "appearance")
+  val appearance: Map<String, String>? = null,
+) {
+  /**
+   * A builder for creating a [CreateConfigurationRequest].
+   * @param participants List of participants included in the scheduled event.
+   * @param availability Rules that determine available time slots for the event.
+   * @param eventBooking Booking data for the event.
+   */
+  data class Builder(
+    private val participants: List<ConfigurationParticipant>,
+    private val availability: ConfigurationAvailability,
+    private val eventBooking: ConfigurationEventBooking,
+  ) {
+    private var requiresSessionAuth: Boolean? = null
+    private var slug: String? = null
+    private var scheduler: ConfigurationSchedulerSettings? = null
+    private var appearance: Map<String, String>? = null
+
+    /**
+     * Set the unique identifier for the configuration.
+     *
+     * @param slug Unique identifier for the Configuration object.
+     * @return The builder
+     */
+    fun slug(slug: String) = apply { this.slug = slug }
+
+    /**
+     * Set if scheduling Availability and Bookings endpoints require a valid session ID.
+     *
+     * @param requiresSessionAuth If true, scheduling Availability and Bookings endpoints require a valid session ID.
+     * @return The builder
+     */
+    fun requiresSessionAuth(requiresSessionAuth: Boolean) = apply { this.requiresSessionAuth = requiresSessionAuth }
+
+    /**
+     * Set the settings for the Scheduler UI.
+     *
+     * @param scheduler Settings for the Scheduler UI.
+     * @return The builder
+     */
+    fun scheduler(scheduler: ConfigurationSchedulerSettings) = apply { this.scheduler = scheduler }
+
+    /**
+     * Set the appearance settings for the Scheduler UI.
+     *
+     * @param appearance Appearance settings for the Scheduler UI.
+     * @return The builder
+     */
+    fun appearance(appearance: Map<String, String>) = apply { this.appearance = appearance }
+
+    /**
+     * Build the [CreateConfigurationRequest].
+     *
+     * @return The [CreateConfigurationRequest]
+     */
+    fun build() = CreateConfigurationRequest(
+      participants,
+      availability,
+      eventBooking,
+      slug,
+      requiresSessionAuth,
+      scheduler,
+      appearance,
+    )
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/CreateSessionRequest.kt b/src/main/kotlin/com/nylas/models/CreateSessionRequest.kt
new file mode 100644
index 00000000..b47a8b39
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/CreateSessionRequest.kt
@@ -0,0 +1,64 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of a request to create a session.
+ */
+data class CreateSessionRequest(
+  /**
+   * The identifier of the Configuration to act upon. If you're using slug, configuration_id is not required.
+   */
+  @Json(name = "configuration_id")
+  val configurationId: String? = null,
+  /**
+   * The time to live for the session.
+   */
+  @Json(name = "time_to_live")
+  val timeToLive: Int? = null,
+
+  /**
+   * The slug of the Scheduler Configuration object for the session. You can use slug instead of configuration_id
+   */
+  @Json(name = "slug")
+  val slug: String? = null,
+) {
+  /**
+   * A builder for creating a [CreateSessionRequest].
+   * @param configurationId The identifier of the Configuration to act upon.
+   * @param timeToLive The time to live for the session.
+   * @param slug The slug of the Scheduler Configuration object for the session.
+   */
+  class Builder {
+    private var configurationId: String? = null
+    private var timeToLive: Int? = null
+    private var slug: String? = null
+
+    /**
+     * Set the configuration ID.
+     * @param configurationId The identifier of the Configuration to act upon.
+     * @return The builder.
+     */
+    fun configurationId(configurationId: String) = apply { this.configurationId = configurationId }
+
+    /**
+     * Set the time to live for the session.
+     * @param timeToLive The time to live for the session.
+     * @return The builder.
+     */
+    fun timeToLive(timeToLive: Int) = apply { this.timeToLive = timeToLive }
+
+    /**
+     * Set the slug of the Scheduler Configuration object for the session.
+     * @param slug The slug of the Scheduler Configuration object for the session.
+     * @return The builder.
+     */
+    fun slug(slug: String) = apply { this.slug = slug }
+
+    /**
+     * Build the [CreateSessionRequest].
+     * @return The [CreateSessionRequest].
+     */
+    fun build() = CreateSessionRequest(configurationId, timeToLive, slug)
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/DestroyBookingQueryParams.kt b/src/main/kotlin/com/nylas/models/DestroyBookingQueryParams.kt
new file mode 100644
index 00000000..34b31e71
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/DestroyBookingQueryParams.kt
@@ -0,0 +1,60 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of the query parameters for destroying a booking.
+ */
+data class DestroyBookingQueryParams(
+  /**
+   * The ID of the Configuration object whose settings are used for calculating availability.
+   */
+  @Json(name = "configuration_id")
+  val configurationId: String? = null,
+  /**
+   * The slug of the Configuration object whose settings are used for calculating availability.
+   */
+  @Json(name = "slug")
+  val slug: String? = null,
+  /**
+   * The client ID that was used to create the Configuration object.
+   */
+  @Json(name = "client_id")
+  val clientId: String? = null,
+) : IQueryParams {
+  /**
+   * Builder for [DestroyBookingQueryParams].
+   */
+  class Builder {
+    private var configurationId: String? = null
+    private var slug: String? = null
+    private var clientId: String? = null
+
+    /**
+     * Sets the ID of the Configuration object whose settings are used for calculating availability.
+     * @param configurationId The ID of the Configuration object whose settings are used for calculating availability.
+     * @return The builder.
+     */
+    fun configurationId(configurationId: String) = apply { this.configurationId = configurationId }
+
+    /**
+     * Sets the slug of the Configuration object whose settings are used for calculating availability.
+     * @param slug The slug of the Configuration object whose settings are used for calculating availability.
+     * @return The builder.
+     */
+    fun slug(slug: String) = apply { this.slug = slug }
+
+    /**
+     * Sets the client ID that was used to create the Configuration object.
+     * @param clientId The client ID that was used to create the Configuration object.
+     * @return The builder.
+     */
+    fun clientId(clientId: String) = apply { this.clientId = clientId }
+
+    /**
+     * Builds a [DestroyBookingQueryParams] instance.
+     * @return The [DestroyBookingQueryParams] instance.
+     */
+    fun build() = DestroyBookingQueryParams(configurationId, slug, clientId)
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/DestroyBookingRequest.kt b/src/main/kotlin/com/nylas/models/DestroyBookingRequest.kt
new file mode 100644
index 00000000..51d86cac
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/DestroyBookingRequest.kt
@@ -0,0 +1,27 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of a request to destroy a booking.
+ */
+data class DestroyBookingRequest(
+  /**
+   * The reason for the cancellation of the booking.
+   */
+  @Json(name = "cancellation_reason")
+  val cancellationReason: String,
+) {
+  /**
+   * Builder for [DestroyBookingRequest].
+   */
+  data class Builder(
+    private val cancellationReason: String,
+  ) {
+    /**
+     * Builds a [DestroyBookingRequest] instance.
+     * @return The [DestroyBookingRequest] instance.
+     */
+    fun build() = DestroyBookingRequest(cancellationReason)
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/EmailLanguage.kt b/src/main/kotlin/com/nylas/models/EmailLanguage.kt
new file mode 100644
index 00000000..ff97cfff
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/EmailLanguage.kt
@@ -0,0 +1,32 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Enum for email language options.
+ */
+enum class EmailLanguage {
+  @Json(name = "en")
+  EN,
+
+  @Json(name = "es")
+  ES,
+
+  @Json(name = "fr")
+  FR,
+
+  @Json(name = "de")
+  DE,
+
+  @Json(name = "nl")
+  NL,
+
+  @Json(name = "sv")
+  SV,
+
+  @Json(name = "ja")
+  JA,
+
+  @Json(name = "zh")
+  ZH,
+}
diff --git a/src/main/kotlin/com/nylas/models/FindBookingQueryParams.kt b/src/main/kotlin/com/nylas/models/FindBookingQueryParams.kt
new file mode 100644
index 00000000..cf728812
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/FindBookingQueryParams.kt
@@ -0,0 +1,63 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of the query parameters for finding a booking.
+ */
+data class FindBookingQueryParams(
+  /**
+   * The ID of the Configuration object whose settings are used for calculating availability.
+   * If you're using session authentication (requires_session_auth is set to true), configuration_id is not required
+   */
+  @Json(name = "configuration_id")
+  val configurationId: String? = null,
+  /**
+   * The slug of the Configuration object whose settings are used for calculating availability.
+   * If you're using session authentication (requires_session_auth is set to true), or using configuration_id, slug is not required
+   */
+  @Json(name = "slug")
+  val slug: String? = null,
+  /**
+   * The client ID that was used to create the Configuration object.
+   *  client_id is required only if using slug.
+   */
+  @Json(name = "client_id")
+  val clientId: String? = null,
+) : IQueryParams {
+  /**
+   * Builder for [FindBookingQueryParams].
+   */
+  class Builder {
+    private var configurationId: String? = null
+    private var slug: String? = null
+    private var clientId: String? = null
+
+    /**
+     * Sets the ID of the Configuration object whose settings are used for calculating availability.
+     * @param configurationId The ID of the Configuration object whose settings are used for calculating availability.
+     * @return The builder.
+     */
+    fun configurationId(configurationId: String) = apply { this.configurationId = configurationId }
+
+    /**
+     * Sets the slug of the Configuration object whose settings are used for calculating availability.
+     * @param slug The slug of the Configuration object whose settings are used for calculating availability.
+     * @return The builder.
+     */
+    fun slug(slug: String) = apply { this.slug = slug }
+
+    /**
+     * Sets the client ID that was used to create the Configuration object.
+     * @param clientId The client ID that was used to create the Configuration object.
+     * @return The builder.
+     */
+    fun clientId(clientId: String) = apply { this.clientId = clientId }
+
+    /**
+     * Builds a [FindBookingQueryParams] instance.
+     * @return The [FindBookingQueryParams] instance.
+     */
+    fun build() = FindBookingQueryParams(configurationId, slug, clientId)
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/ListConfigurationsQueryParams.kt b/src/main/kotlin/com/nylas/models/ListConfigurationsQueryParams.kt
new file mode 100644
index 00000000..29656c5c
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/ListConfigurationsQueryParams.kt
@@ -0,0 +1,50 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+data class ListConfigurationsQueryParams(
+  /**
+   * The maximum number of objects to return.
+   * Defaults to 50. The maximum allowed value is 200.
+   */
+  @Json(name = "limit")
+  val limit: Int? = null,
+  /**
+   * An identifier that specifies which page of data to return.
+   * This value should be taken from the [ListResponse.nextCursor] response field.
+   */
+  @Json(name = "page_token")
+  val pageToken: String? = null,
+) : IQueryParams
+
+/**
+ * Builder for [ListConfigurationsQueryParams].
+ */
+class Builder {
+  private var limit: Int? = null
+  private var pageToken: String? = null
+
+  /**
+   * Sets the maximum number of objects to return.
+   * This field defaults to 50. The maximum allowed value is 200.
+   * @param limit The maximum number of objects to return.
+   * @return The builder.
+   */
+
+  fun limit(limit: Int?) = apply { this.limit = limit }
+
+  /**
+   * Sets the identifier that specifies which page of data to return.
+   * This value should be taken from the next_cursor response field.
+   * @param pageToken The identifier that specifies which page of data to return.
+   * @return The builder.
+   */
+
+  fun pageToken(pageToken: String?) = apply { this.pageToken = pageToken }
+
+  /**
+   * Builds a [ListConfigurationsQueryParams] instance.
+   * @return The [ListConfigurationsQueryParams] instance.
+   */
+  fun build() = ListConfigurationsQueryParams(limit, pageToken)
+}
diff --git a/src/main/kotlin/com/nylas/models/RescheduleBookingQueryParams.kt b/src/main/kotlin/com/nylas/models/RescheduleBookingQueryParams.kt
new file mode 100644
index 00000000..74228046
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/RescheduleBookingQueryParams.kt
@@ -0,0 +1,55 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of the query parameters for rescheduling a booking.
+ */
+data class RescheduleBookingQueryParams(
+  /**
+   * The ID of the Configuration object whose settings are used for calculating availability.
+   */
+  @Json(name = "configuration_id")
+  val configurationId: String,
+  /**
+   * The slug of the Configuration object whose settings are used for calculating availability.
+   */
+  @Json(name = "slug")
+  val slug: String,
+  /**
+   * The client ID that was used to create the Configuration object.
+   */
+  @Json(name = "client_id")
+  val clientId: String,
+) : IQueryParams {
+  /**
+   * Builder for [RescheduleBookingQueryParams].
+   */
+  class Builder {
+    private var configurationId: String? = null
+    private var slug: String? = null
+    private var clientId: String? = null
+
+    /**
+     * Sets the ID of the Configuration object whose settings are used for calculating availability.
+     * @param configurationId The ID of the Configuration object whose settings are used for calculating availability.
+     * @return The builder.
+     */
+    fun configurationId(configurationId: String) = apply { this.configurationId = configurationId }
+
+    /**
+     * Sets the slug of the Configuration object whose settings are used for calculating availability.
+     * @param slug The slug of the Configuration object whose settings are used for calculating availability.
+     * @return The builder.
+     */
+    fun slug(slug: String) = apply { this.slug = slug }
+
+    /**
+     * Sets the client ID that was used to create the Configuration object.
+     * @param clientId The client ID that was used to create the Configuration object.
+     * @return The builder.
+     */
+    fun clientId(clientId: String) = apply { this.clientId = clientId }
+  }
+  fun build() = RescheduleBookingQueryParams(configurationId, slug, clientId)
+}
diff --git a/src/main/kotlin/com/nylas/models/RescheduleBookingRequest.kt b/src/main/kotlin/com/nylas/models/RescheduleBookingRequest.kt
new file mode 100644
index 00000000..d0bfdd62
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/RescheduleBookingRequest.kt
@@ -0,0 +1,44 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+data class RescheduleBookingRequest(
+  /**
+   * The event's start time, in Unix epoch format.
+   */
+  @Json(name = "start_time")
+  val startTime: Int? = null,
+  /**
+   * The event's end time, in Unix epoch format.
+   */
+  @Json(name = "end_time")
+  val endTime: Int? = null,
+) {
+  /**
+   * Builder for [RescheduleBookingRequest].
+   */
+  class Builder {
+    private var startTime: Int? = null
+    private var endTime: Int? = null
+
+    /**
+     * Set the start time of the booking.
+     * @param startTime The start time of the booking.
+     * @return The builder.
+     */
+    fun startTime(startTime: Int) = apply { this.startTime = startTime }
+
+    /**
+     * Set the end time of the booking.
+     * @param endTime The end time of the booking.
+     * @return The builder.
+     */
+    fun endTime(endTime: Int) = apply { this.endTime = endTime }
+
+    /**
+     * Builds a [RescheduleBookingRequest] instance.
+     * @return The [RescheduleBookingRequest] instance.
+     */
+    fun build() = RescheduleBookingRequest(startTime, endTime)
+  }
+}
diff --git a/src/main/kotlin/com/nylas/models/Scheduler.kt b/src/main/kotlin/com/nylas/models/Scheduler.kt
new file mode 100644
index 00000000..026491c9
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/Scheduler.kt
@@ -0,0 +1,104 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of a Nylas scheduler configuration.
+ */
+data class Configuration(
+  /**
+   * Globally unique object identifier.
+   */
+  @Json(name = "id")
+  val id: String,
+  /**
+   * List of participants included in the scheduled event.
+   */
+  @Json(name = "participants")
+  val participants: List<ConfigurationParticipant>,
+  /**
+   * Rules that determine available time slots for the event.
+   */
+  @Json(name = "availability")
+  val availability: ConfigurationAvailability,
+  /**
+   * Booking data for the event.
+   */
+  @Json(name = "event_booking")
+  val eventBooking: ConfigurationEventBooking,
+  /**
+   * Unique identifier for the Configuration object.
+   */
+  @Json(name = "slug")
+  val slug: String? = null,
+  /**
+   * If true, scheduling Availability and Bookings endpoints require a valid session ID.
+   */
+  @Json(name = "requires_session_auth")
+  val requiresSessionAuth: Boolean? = null,
+  /**
+   * Settings for the Scheduler UI.
+   */
+  @Json(name = "scheduler")
+  val scheduler: ConfigurationSchedulerSettings? = null,
+  /**
+   * Appearance settings for the Scheduler UI.
+   */
+  @Json(name = "appearance")
+  val appearance: Map<String, String>? = null,
+)
+
+/**
+ * Class representation of a session.
+ */
+data class Session(
+  /**
+   * The ID of the session.
+   */
+  @Json(name = "session_id")
+  val sessionId: String,
+)
+
+/**
+ * Class representation of a booking.
+ */
+data class Booking(
+  /**
+   * The unique ID of the booking.
+   */
+  @Json(name = "booking_id")
+  val bookingId: String,
+  /**
+   * The unique ID of the event associated with the booking.
+   */
+  @Json(name = "event_id")
+  val eventId: String,
+  /**
+   * The title of the event.
+   */
+  @Json(name = "title")
+  val title: String,
+  /**
+   * The participant designated as the organizer of the event.
+   */
+  @Json(name = "organizer")
+  val organizer: BookingOrganizer,
+  /**
+   * The current status of the booking.
+   */
+  @Json(name = "status")
+  val status: BookingStatus,
+  /**
+   * The description of the event.
+   */
+  @Json(name = "description")
+  val description: String? = null,
+)
+
+/**
+ * Class representation of a booking participant.
+ */
+data class BookingParticipant(
+  @Json(name = "email")
+  val email: String,
+)
diff --git a/src/main/kotlin/com/nylas/models/UpdateConfigurationRequest.kt b/src/main/kotlin/com/nylas/models/UpdateConfigurationRequest.kt
new file mode 100644
index 00000000..3386ee0f
--- /dev/null
+++ b/src/main/kotlin/com/nylas/models/UpdateConfigurationRequest.kt
@@ -0,0 +1,125 @@
+package com.nylas.models
+
+import com.squareup.moshi.Json
+
+/**
+ * Class representation of a request to update a configuration.
+ */
+data class UpdateConfigurationRequest(
+  /**
+   * List of participants included in the scheduled event.
+   */
+  @Json(name = "participants")
+  val participants: List<ConfigurationParticipant>? = null,
+  /**
+   * Rules that determine available time slots for the event.
+   */
+  @Json(name = "availability")
+  val availability: ConfigurationAvailability? = null,
+  /**
+   * Booking data for the event.
+   */
+  @Json(name = "event_booking")
+  val eventBooking: ConfigurationEventBooking? = null,
+  /**
+   * Unique identifier for the Configuration object.
+   */
+  @Json(name = "slug")
+  val slug: String? = null,
+  /**
+   * If true, scheduling Availability and Bookings endpoints require a valid session ID.
+   */
+  @Json(name = "requires_session_auth")
+  val requiresSessionAuth: Boolean? = null,
+  /**
+   * Settings for the Scheduler UI.
+   */
+  @Json(name = "scheduler")
+  val scheduler: ConfigurationSchedulerSettings? = null,
+  /**
+   * Appearance settings for the Scheduler UI.
+   */
+  @Json(name = "appearance")
+  val appearance: Map<String, String>? = null,
+) {
+  /**
+   * A builder for creating a [UpdateConfigurationRequest].
+   */
+  class Builder {
+    private var participants: List<ConfigurationParticipant>? = null
+    private var availability: ConfigurationAvailability? = null
+    private var eventBooking: ConfigurationEventBooking? = null
+    private var requiresSessionAuth: Boolean? = null
+    private var slug: String? = null
+    private var scheduler: ConfigurationSchedulerSettings? = null
+    private var appearance: Map<String, String>? = null
+
+    /**
+     * Set the list of participants included in the scheduled event.
+     * @param participants List of participants included in the scheduled event.
+     * @return The builder
+     */
+    fun participants(participants: List<ConfigurationParticipant>) = apply { this.participants = participants }
+
+    /**
+     * Set the rules that determine available time slots for the event.
+     * @param availability Rules that determine available time slots for the event.
+     * @return The builder
+     */
+    fun availability(availability: ConfigurationAvailability) = apply { this.availability = availability }
+
+    /**
+     * Set the booking data for the event.
+     * @param eventBooking Booking data for the event.
+     * @return The builder
+     */
+    fun eventBooking(eventBooking: ConfigurationEventBooking) = apply { this.eventBooking = eventBooking }
+
+    /**
+     * Set the unique identifier for the configuration.
+     *
+     * @param slug Unique identifier for the Configuration object.
+     * @return The builder
+     */
+    fun slug(slug: String) = apply { this.slug = slug }
+
+    /**
+     * Set if scheduling Availability and Bookings endpoints require a valid session ID.
+     *
+     * @param requiresSessionAuth If true, scheduling Availability and Bookings endpoints require a valid session ID.
+     * @return The builder
+     */
+    fun requiresSessionAuth(requiresSessionAuth: Boolean) = apply { this.requiresSessionAuth = requiresSessionAuth }
+
+    /**
+     * Set the settings for the Scheduler UI.
+     *
+     * @param scheduler Settings for the Scheduler UI.
+     * @return The builder
+     */
+    fun scheduler(scheduler: ConfigurationSchedulerSettings) = apply { this.scheduler = scheduler }
+
+    /**
+     * Set the appearance settings for the Scheduler UI.
+     *
+     * @param appearance Appearance settings for the Scheduler UI.
+     * @return The builder
+     */
+    fun appearance(appearance: Map<String, String>) = apply { this.appearance = appearance }
+
+    /**
+     * Build the [UpdateConfigurationRequest].
+     *
+     * @return The [UpdateConfigurationRequest]
+     */
+    fun build() = UpdateConfigurationRequest(
+      participants,
+      availability,
+      eventBooking,
+      slug,
+      requiresSessionAuth,
+      scheduler,
+      appearance,
+    )
+  }
+}
diff --git a/src/main/kotlin/com/nylas/resources/Bookings.kt b/src/main/kotlin/com/nylas/resources/Bookings.kt
new file mode 100644
index 00000000..bdebdd7f
--- /dev/null
+++ b/src/main/kotlin/com/nylas/resources/Bookings.kt
@@ -0,0 +1,107 @@
+package com.nylas.resources
+
+import com.nylas.NylasClient
+import com.nylas.models.*
+import com.nylas.util.JsonHelper
+
+/**
+ * Nylas Bookings API
+ *
+ * The Nylas Bookings API allows you to create new bookings or manage existing ones, as well as getting
+ * bookings details for a user.
+ */
+class Bookings(client: NylasClient) : Resource<Booking>(client, Booking::class.java) {
+  /**
+   * Find a booking
+   * @param bookingId The ID of the booking to find.
+   * @param queryParams Optional query parameters to apply
+   * @param overrides Optional request overrides to apply
+   * @return The Booking object
+   */
+  @Throws(NylasApiError::class, NylasSdkTimeoutError::class)
+  @JvmOverloads
+  fun find(
+    bookingId: String,
+    queryParams: FindBookingQueryParams? = null,
+    overrides: RequestOverrides? = null,
+  ): Response<Booking> {
+    val path = String.format("v3/scheduling/bookings/%s", bookingId)
+    return findResource(path, queryParams, overrides = overrides)
+  }
+
+  /**
+   * Create a booking
+   * @param requestBody The data to create the booking with.
+   * @param queryParams Optional query parameters to apply
+   * @param overrides Optional request overrides to apply
+   * @return The Booking object
+   */
+  @Throws(NylasApiError::class, NylasSdkTimeoutError::class)
+  @JvmOverloads
+  fun create(
+    requestBody: CreateBookingRequest,
+    queryParams: CreateBookingQueryParams? = null,
+    overrides: RequestOverrides? = null,
+  ): Response<Booking> {
+    val path = "v3/scheduling/bookings"
+    val adapter = JsonHelper.moshi().adapter(CreateBookingRequest::class.java)
+    val serializedRequestBody = adapter.toJson(requestBody)
+    return createResource(path, serializedRequestBody, queryParams, overrides = overrides)
+  }
+
+  /**
+   * Confirm a booking
+   * @param bookingId The ID of the booking to update.
+   * @param requestBody The data to update the booking with.
+   * @param queryParams Optional query parameters to apply
+   * @param overrides Optional request overrides to apply
+   * @return The Booking object
+   */
+  @Throws(NylasApiError::class, NylasSdkTimeoutError::class)
+  @JvmOverloads
+  fun confirm(
+    bookingId: String,
+    requestBody: ConfirmBookingRequest,
+    queryParams: ConfirmBookingQueryParams? = null,
+    overrides: RequestOverrides? = null,
+  ): Response<Booking> {
+    val path = String.format("v3/scheduling/bookings/%s", bookingId)
+    val adapter = JsonHelper.moshi().adapter(ConfirmBookingRequest::class.java)
+    val serializedRequestBody = adapter.toJson(requestBody)
+    return updateResource(path, serializedRequestBody, queryParams, overrides = overrides)
+  }
+
+  /**
+   * Reschedule a booking
+   * @param bookingId The ID of the booking to update.
+   * @param requestBody The data to update the booking with.
+   * @param queryParams Optional query parameters to apply
+   * @param overrides Optional request overrides to apply
+   * @return The Booking object
+   */
+  @Throws(NylasApiError::class, NylasSdkTimeoutError::class)
+  @JvmOverloads
+  fun reschedule(
+    bookingId: String,
+    requestBody: RescheduleBookingRequest,
+    queryParams: RescheduleBookingQueryParams? = null,
+    overrides: RequestOverrides? = null,
+  ): Response<Booking> {
+    val path = String.format("v3/scheduling/bookings/%s", bookingId)
+    val adapter = JsonHelper.moshi().adapter(RescheduleBookingRequest::class.java)
+    val serializedRequestBody = adapter.toJson(requestBody)
+    return patchResource(path, serializedRequestBody, queryParams, overrides = overrides)
+  }
+
+  /**
+   * Destroy a booking
+   * @param bookingId The ID of the booking to destroy.
+   * @param queryParams Optional query parameters to apply
+   * @param overrides Optional request overrides to apply
+   * @return The DeleteResponse object
+   */
+  fun destroy(bookingId: String, queryParams: DestroyBookingQueryParams? = null, overrides: RequestOverrides? = null): DeleteResponse {
+    val path = String.format("v3/scheduling/bookings/%s", bookingId)
+    return destroyResource(path, queryParams, overrides = overrides)
+  }
+}
diff --git a/src/main/kotlin/com/nylas/resources/Configurations.kt b/src/main/kotlin/com/nylas/resources/Configurations.kt
new file mode 100644
index 00000000..cffc1ee4
--- /dev/null
+++ b/src/main/kotlin/com/nylas/resources/Configurations.kt
@@ -0,0 +1,114 @@
+package com.nylas.resources
+
+import com.nylas.NylasClient
+import com.nylas.models.*
+import com.nylas.util.JsonHelper
+
+/**
+ * Nylas Configurations API
+ *
+ * The Nylas configurations API allows you to create new configurations or manage existing ones, as well as getting
+ * configurations details for a user.
+ *
+ * Nylas Scheduler stores Configuration objects in the Scheduler database and loads
+ * them as Scheduling Pages in the Scheduler UI.
+ *
+ * @param client The configured Nylas API client
+ */
+class Configurations(client: NylasClient) : Resource<Configuration>(client, Configuration::class.java) {
+
+  /**
+   * Return all Configurations
+   * @param identifier The identifier of the Grant to act upon.
+   * @param queryParams The query parameters to include in the request
+   * @param overrides Optional request overrides to apply
+   * @return The list of Configurations
+   */
+  @Throws(NylasApiError::class, NylasSdkTimeoutError::class)
+  @JvmOverloads
+  fun list(
+    identifier: String,
+    queryParams: ListConfigurationsQueryParams? = null,
+    overrides: RequestOverrides? = null,
+  ): ListResponse<Configuration> {
+    val path = String.format("v3/grants/%s/scheduling/configurations", identifier)
+    return listResource(path, queryParams, overrides)
+  }
+
+  /**
+   * Return a Configuration
+   * @param identifier The identifier of the Grant to act upon.
+   * @param configId The identifier of the Configuration to get.
+   * @param overrides Optional request overrides to apply
+   * @return The Configuration object
+   */
+  @Throws(NylasApiError::class, NylasSdkTimeoutError::class)
+  @JvmOverloads
+  fun find(
+    identifier: String,
+    configId: String,
+    overrides: RequestOverrides? = null,
+  ): Response<Configuration> {
+    val path = String.format("v3/grants/%s/scheduling/configurations/%s", identifier, configId)
+    return findResource(path, overrides = overrides)
+  }
+
+  /**
+   * Create a new Configuration
+   * @param identifier The identifier of the Grant to act upon.
+   * @param requestBody The data to create the Configuration with.
+   * @param overrides Optional request overrides to apply
+   * @return The Configuration object
+   */
+  @Throws(NylasApiError::class, NylasSdkTimeoutError::class)
+  @JvmOverloads
+  fun create(
+    identifier: String,
+    requestBody: CreateConfigurationRequest,
+    overrides: RequestOverrides? = null,
+  ): Response<Configuration> {
+    val path = String.format("v3/grants/%s/scheduling/configurations", identifier)
+    val adapter = JsonHelper.moshi().adapter(CreateConfigurationRequest::class.java)
+    val serializedRequestBody = adapter.toJson(requestBody)
+    return createResource(path, serializedRequestBody, overrides = overrides)
+  }
+
+  /**
+   * Update a Configuration
+   * @param identifier The identifier of the Grant to act upon.
+   * @param configId The identifier of the Configuration to update.
+   * @param requestBody The data to update the Configuration with.
+   * @param overrides Optional request overrides to apply
+   * @return The Configuration object
+   */
+  @Throws(NylasApiError::class, NylasSdkTimeoutError::class)
+  @JvmOverloads
+  fun update(
+    identifier: String,
+    configId: String,
+    requestBody: UpdateConfigurationRequest,
+    overrides: RequestOverrides? = null,
+  ): Response<Configuration> {
+    val path = String.format("v3/grants/%s/scheduling/configurations/%s", identifier, configId)
+    val adapter = JsonHelper.moshi().adapter(UpdateConfigurationRequest::class.java)
+    val serializedRequestBody = adapter.toJson(requestBody)
+    return updateResource(path, serializedRequestBody, overrides = overrides)
+  }
+
+  /**
+   * Delete a Configuration
+   * @param identifier The identifier of the Grant to act upon.
+   * @param configId The identifier of the Configuration to delete.
+   * @param overrides Optional request overrides to apply
+   * @return The deletion response
+   */
+  @Throws(NylasApiError::class, NylasSdkTimeoutError::class)
+  fun destroy(
+    identifier: String,
+    configId: String,
+    overrides: RequestOverrides? = null,
+  ): DeleteResponse {
+    val path = String.format("v3/grants/%s/scheduling/configurations/%s", identifier, configId)
+    return destroyResource(path, overrides = overrides)
+  }
+}
diff --git a/src/main/kotlin/com/nylas/resources/Scheduler.kt b/src/main/kotlin/com/nylas/resources/Scheduler.kt
new file mode 100644
index 00000000..4388878f
--- /dev/null
+++ b/src/main/kotlin/com/nylas/resources/Scheduler.kt
@@ -0,0 +1,34 @@
+package com.nylas.resources
+
+import com.nylas.NylasClient
+
+/**
+ * Nylas Scheduler API
+ *
+ * The Nylas Scheduler API allows you to manage scheduling configurations, bookings, and sessions.
+ *
+ * @param client The configured Nylas API client
+ */
+class Scheduler(private val client: NylasClient) {
+
+  /**
+   * Access the Configurations API.
+   *
+   * @return The Configurations API.
+   */
+  fun configurations(): Configurations = Configurations(client)
+
+  /**
+   * Access the Sessions API.
+   *
+   * @return The Sessions API.
+   */
+  fun sessions(): Sessions = Sessions(client)
+
+  /**
+   * Access the Bookings API.
+   *
+   * @return The Bookings API.
+   */
+  fun bookings(): Bookings = Bookings(client)
+}
diff --git a/src/main/kotlin/com/nylas/resources/Sessions.kt b/src/main/kotlin/com/nylas/resources/Sessions.kt
new file mode 100644
index 00000000..2deea690
--- /dev/null
+++ b/src/main/kotlin/com/nylas/resources/Sessions.kt
@@ -0,0 +1,41 @@
+package com.nylas.resources
+
+import com.nylas.NylasClient
+import com.nylas.models.*
+import com.nylas.util.JsonHelper
+/**
+ * Nylas Sessions API
+ *
+ * The Nylas Sessions API allows you to create and delete sessions on user Schedulerconfigurations.
+ *
+ * @param client The configured Nylas API client
+ */
+class Sessions(client: NylasClient) : Resource<Session>(client, Session::class.java) {
+  /**
+   * Create a Session
+   * @param requestBody The values to create the session with
+   * @param overrides Optional request overrides to apply
+   * @return The created session
+   */
+  @Throws(NylasApiError::class, NylasSdkTimeoutError::class)
+  @JvmOverloads
+  fun create(requestBody: CreateSessionRequest, overrides: RequestOverrides? = null): Response<Session> {
+    val path = "v3/scheduling/sessions"
+    val adapter = JsonHelper.moshi().adapter(CreateSessionRequest::class.java)
+    val serializedRequestBody = adapter.toJson(requestBody)
+    return createResource(path, serializedRequestBody, overrides = overrides)
+  }
+
+  /**
+   * Delete a Session
+   * @param sessionId The ID of the session to delete
+   * @param overrides Optional request overrides to apply
+   * @return The deleted response
+   */
+  @Throws(NylasApiError::class, NylasSdkTimeoutError::class)
+  @JvmOverloads
+  fun destroy(sessionId: String, overrides: RequestOverrides? = null): DeleteResponse {
+    val path = String.format("v3/scheduling/sessions/%s", sessionId)
+    return destroyResource(path, overrides = overrides)
+  }
+}
diff --git a/src/test/kotlin/com/nylas/resources/BookingsTest.kt b/src/test/kotlin/com/nylas/resources/BookingsTest.kt
new file mode 100644
index 00000000..137950e3
--- /dev/null
+++ b/src/test/kotlin/com/nylas/resources/BookingsTest.kt
@@ -0,0 +1,189 @@
+package com.nylas.resources
+
+import com.nylas.NylasClient
+import com.nylas.models.*
+import com.nylas.models.Response
+import com.nylas.util.JsonHelper
+import com.squareup.moshi.Types
+import okhttp3.*
+import okio.Buffer
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Nested
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.*
+import java.lang.reflect.Type
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertIs
+
+class BookingsTest {
+  private val mockHttpClient: OkHttpClient = Mockito.mock(OkHttpClient::class.java)
+  private val mockCall: Call = Mockito.mock(Call::class.java)
+  private val mockResponse: okhttp3.Response = Mockito.mock(okhttp3.Response::class.java)
+  private val mockResponseBody: ResponseBody = Mockito.mock(ResponseBody::class.java)
+  private val mockOkHttpClientBuilder: OkHttpClient.Builder = Mockito.mock()
+
+  @BeforeEach
+  fun setUp() {
+    MockitoAnnotations.openMocks(this)
+    whenever(mockOkHttpClientBuilder.addInterceptor(any())).thenReturn(mockOkHttpClientBuilder)
+    whenever(mockOkHttpClientBuilder.build()).thenReturn(mockHttpClient)
+    whenever(mockHttpClient.newCall(any())).thenReturn(mockCall)
+    whenever(mockCall.execute()).thenReturn(mockResponse)
+    whenever(mockResponse.isSuccessful).thenReturn(true)
+    whenever(mockResponse.body()).thenReturn(mockResponseBody)
+  }
+
+  @Nested
+  inner class SerializationTests {
+    @Test
+    fun `Booking serializes properly`() {
+      val adapter = JsonHelper.moshi().adapter(Booking::class.java)
+      val jsonBuffer = Buffer().writeUtf8(
+        """
+      {
+        "booking_id": "booking-123",
+        "event_id": "event-123",
+        "title": "My test event",
+        "organizer": {
+          "name": "John Doe",
+          "email": "user@example.com"
+        },
+        "status": "booked",
+        "description": "This is an example of a description."
+      }
+        """.trimIndent(),
+      )
+
+      val booking = adapter.fromJson(jsonBuffer)
+      assertIs<Booking>(booking)
+      assertEquals("booking-123", booking.bookingId)
+      assertEquals("event-123", booking.eventId)
+      assertEquals("My test event", booking.title)
+      assertEquals("John Doe", booking.organizer.name)
+      assertEquals("user@example.com", booking.organizer.email)
+      assertEquals(BookingStatus.BOOKED, booking.status)
+      assertEquals("This is an example of a description.", booking.description)
+    }
+  }
+
+  @Nested
+  inner class CrudTests {
+    private lateinit var mockNylasClient: NylasClient
+    private lateinit var bookings: Bookings
+
+    @BeforeEach
+    fun setup() {
+      mockNylasClient = Mockito.mock(NylasClient::class.java)
+      bookings = Bookings(mockNylasClient)
+    }
+
+    @Test
+    fun `creating a booking calls requests with the correct params`() {
+      val adapter = JsonHelper.moshi().adapter(CreateBookingRequest::class.java)
+      val participants = ArrayList<BookingParticipant>()
+      val bookingParticipant = BookingParticipant("test@nylas.com")
+      participants.add(bookingParticipant)
+
+      val bookingGuest = BookingGuest("guest@nylas.com", "Guest")
+      val startTime = "1630000000"
+      val endTime = "1630003600"
+
+      val createBookingRequest = CreateBookingRequest(
+        startTime = startTime,
+        endTime = endTime,
+        participants = participants,
+        guest = bookingGuest,
+      )
+
+      bookings.create(createBookingRequest)
+
+      val pathCaptor = argumentCaptor<String>()
+      val typeCaptor = argumentCaptor<Type>()
+      val requestBodyCaptor = argumentCaptor<String>()
+      val queryParamCaptor = argumentCaptor<CreateBookingQueryParams>()
+      val overrideParamCaptor = argumentCaptor<RequestOverrides>()
+      verify(mockNylasClient).executePost<Booking>(pathCaptor.capture(), typeCaptor.capture(), requestBodyCaptor.capture(), queryParamCaptor.capture(), overrideParamCaptor.capture())
+
+      assertEquals("v3/scheduling/bookings", pathCaptor.firstValue)
+      assertEquals(Types.newParameterizedType(Response::class.java, Booking::class.java), typeCaptor.firstValue)
+      assertEquals(adapter.toJson(createBookingRequest), requestBodyCaptor.firstValue)
+    }
+
+    @Test
+    fun `finding a booking calls requests with the correct params`() {
+      val bookingId = "booking-id"
+      bookings.find(bookingId)
+
+      val pathCaptor = argumentCaptor<String>()
+      val typeCaptor = argumentCaptor<Type>()
+      val queryParamCaptor = argumentCaptor<FindBookingQueryParams>()
+      val overrideParamCaptor = argumentCaptor<RequestOverrides>()
+      verify(mockNylasClient).executeGet<Booking>(pathCaptor.capture(), typeCaptor.capture(), queryParamCaptor.capture(), overrideParamCaptor.capture())
+
+      assertEquals("v3/scheduling/bookings/$bookingId", pathCaptor.firstValue)
+      assertEquals(Types.newParameterizedType(Response::class.java, Booking::class.java), typeCaptor.firstValue)
+    }
+
+    @Test
+    fun `rescheduling a booking calls requests with the correct params`() {
+      val adapter = JsonHelper.moshi().adapter(RescheduleBookingRequest::class.java)
+      val bookingId = "booking-id"
+      val rescheduleBookingRequest = RescheduleBookingRequest(
+        startTime = 1630000000,
+        endTime = 1630003600,
+      )
+      bookings.reschedule(bookingId, rescheduleBookingRequest)
+
+      val pathCaptor = argumentCaptor<String>()
+      val typeCaptor = argumentCaptor<Type>()
+      val requestBodyCaptor = argumentCaptor<String>()
+      val queryParamCaptor = argumentCaptor<RescheduleBookingQueryParams>()
+      val overrideParamCaptor = argumentCaptor<RequestOverrides>()
+      verify(mockNylasClient).executePatch<Booking>(pathCaptor.capture(), typeCaptor.capture(), requestBodyCaptor.capture(), queryParamCaptor.capture(), overrideParamCaptor.capture())
+
+      assertEquals("v3/scheduling/bookings/$bookingId", pathCaptor.firstValue)
+      assertEquals(Types.newParameterizedType(Response::class.java, Booking::class.java), typeCaptor.firstValue)
+      assertEquals(adapter.toJson(rescheduleBookingRequest), requestBodyCaptor.firstValue)
+    }
+
+    @Test
+    fun `confirming a booking calls requests with the correct params`() {
+      val adapter = JsonHelper.moshi().adapter(ConfirmBookingRequest::class.java)
+      val bookingId = "booking-id"
+      val confirmBookingRequest = ConfirmBookingRequest(
+        salt = "salt123",
+        status = ConfirmBookingStatus.CANCELLED,
+      )
+
+      bookings.confirm(bookingId, confirmBookingRequest)
+
+      val pathCaptor = argumentCaptor<String>()
+      val typeCaptor = argumentCaptor<Type>()
+      val requestBodyCaptor = argumentCaptor<String>()
+      val queryParamCaptor = argumentCaptor<ConfirmBookingQueryParams>()
+      val overrideParamCaptor = argumentCaptor<RequestOverrides>()
+      verify(mockNylasClient).executePut<Booking>(pathCaptor.capture(), typeCaptor.capture(), requestBodyCaptor.capture(), queryParamCaptor.capture(), overrideParamCaptor.capture())
+
+      assertEquals("v3/scheduling/bookings/$bookingId", pathCaptor.firstValue)
+      assertEquals(Types.newParameterizedType(Response::class.java, Booking::class.java), typeCaptor.firstValue)
+      assertEquals(adapter.toJson(confirmBookingRequest), requestBodyCaptor.firstValue)
+    }
+
+    @Test
+    fun `destryoing a booking calls request with the correct params`() {
+      val bookingId = "booking-id"
+      bookings.destroy(bookingId)
+
+      val pathCaptor = argumentCaptor<String>()
+      val typeCaptor = argumentCaptor<Type>()
+      val queryParamCaptor = argumentCaptor<DestroyBookingQueryParams>()
+      val overrideParamCaptor = argumentCaptor<RequestOverrides>()
+      verify(mockNylasClient).executeDelete<DeleteResponse>(pathCaptor.capture(), typeCaptor.capture(), queryParamCaptor.capture(), overrideParamCaptor.capture())
+
+      assertEquals("v3/scheduling/bookings/$bookingId", pathCaptor.firstValue)
+      assertEquals(DeleteResponse::class.java, typeCaptor.firstValue)
+    }
+  }
+}
diff --git a/src/test/kotlin/com/nylas/resources/CalendarsTest.kt b/src/test/kotlin/com/nylas/resources/CalendarsTest.kt
index 05d2d731..f9b88ea6 100644
--- a/src/test/kotlin/com/nylas/resources/CalendarsTest.kt
+++ b/src/test/kotlin/com/nylas/resources/CalendarsTest.kt
@@ -264,7 +264,7 @@ class CalendarsTest {
               exdates = listOf("2021-05-03", "2021-05-04"),
             ),
           ),
-          roundRobinEventId = "event-123",
+          roundRobinGroupId = "event-123",
         ),
       )
 
diff --git a/src/test/kotlin/com/nylas/resources/ConfigurationsTest.kt b/src/test/kotlin/com/nylas/resources/ConfigurationsTest.kt
new file mode 100644
index 00000000..7fb5f34c
--- /dev/null
+++ b/src/test/kotlin/com/nylas/resources/ConfigurationsTest.kt
@@ -0,0 +1,328 @@
+package com.nylas.resources
+
+import com.nylas.NylasClient
+import com.nylas.models.*
+import com.nylas.models.ListConfigurationsQueryParams
+import com.nylas.models.Response
+import com.nylas.util.JsonHelper
+import com.squareup.moshi.Types
+import okhttp3.*
+import okio.Buffer
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Nested
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.*
+import java.lang.reflect.Type
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertIs
+
+class ConfigurationsTest {
+  private val mockHttpClient: OkHttpClient = Mockito.mock(OkHttpClient::class.java)
+  private val mockCall: Call = Mockito.mock(Call::class.java)
+  private val mockResponse: okhttp3.Response = Mockito.mock(okhttp3.Response::class.java)
+  private val mockResponseBody: ResponseBody = Mockito.mock(ResponseBody::class.java)
+  private val mockOkHttpClientBuilder: OkHttpClient.Builder = Mockito.mock()
+
+  @BeforeEach
+  fun setup() {
+    MockitoAnnotations.openMocks(this)
+    whenever(mockOkHttpClientBuilder.addInterceptor(any())).thenReturn(mockOkHttpClientBuilder)
+    whenever(mockOkHttpClientBuilder.build()).thenReturn(mockHttpClient)
+    whenever(mockHttpClient.newCall(any())).thenReturn(mockCall)
+    whenever(mockCall.execute()).thenReturn(mockResponse)
+    whenever(mockResponse.isSuccessful).thenReturn(true)
+    whenever(mockResponse.body()).thenReturn(mockResponseBody)
+  }
+
+  @Nested
+  inner class SerializationTests {
+    @Test
+    fun `Configuration serializes properly`() {
+      val adapter = JsonHelper.moshi().adapter(Configuration::class.java)
+      val jsonBuffer = Buffer().writeUtf8(
+        """
+        {
+          "id": "abc-123-configuration-id",
+          "slug": null,
+          "participants": [
+              {
+                  "email": "test@nylas.com",
+                  "is_organizer": true,
+                  "name": "Test",
+                  "availability": {
+                      "calendar_ids": [
+                          "primary"
+                      ],
+                      "open_hours": [
+                          {
+                              "days": [
+                                  0,
+                                  1,
+                                  2,
+                                  3,
+                                  4,
+                                  5,
+                                  6
+                              ],
+                              "exdates": null,
+                              "timezone": "",
+                              "start": "09:00",
+                              "end": "17:00"
+                          }
+                      ]
+                  },
+                  "booking": {
+                      "calendar_id": "primary"
+                  },
+                  "timezone": ""
+              }
+          ],
+          "requires_session_auth": false,
+          "availability": {
+              "duration_minutes": 30,
+              "interval_minutes": 15,
+              "round_to": 15,
+              "availability_rules": {
+                  "availability_method": "collective",
+                  "buffer": {
+                      "before": 60,
+                      "after": 0
+                  },
+                  "default_open_hours": [
+                      {
+                          "days": [
+                              0,
+                              1,
+                              2,
+                              5,
+                              6
+                          ],
+                          "exdates": null,
+                          "timezone": "",
+                          "start": "09:00",
+                          "end": "18:00"
+                      }
+                  ],
+                  "round_robin_group_id": ""
+              }
+          },
+          "event_booking": {
+              "title": "Updated Title",
+              "timezone": "utc",
+              "description": "",
+              "location": null,
+              "booking_type": "booking",
+              "conferencing": {
+                  "provider": "Microsoft Teams",
+                  "autocreate": {
+                      "conf_grant_id": "",
+                      "conf_settings": null
+                  }
+              },
+              "hide_participants": null,
+              "disable_emails": null
+          },
+          "scheduler": {
+              "available_days_in_future": 7,
+              "min_cancellation_notice": 60,
+              "min_booking_notice": 120,
+              "confirmation_redirect_url": "",
+              "hide_rescheduling_options": false,
+              "hide_cancellation_options": false,
+              "hide_additional_guests": true,
+              "cancellation_policy": "",
+              "email_template": {
+                  "booking_confirmed": {}
+              }
+          },
+          "appearance": {
+              "submit_button_label": "submit",
+              "thank_you_message": "thank you for your business. your booking was successful."
+          }
+        }
+        """.trimIndent(),
+      )
+
+      val config = adapter.fromJson(jsonBuffer)!!
+      assertIs<Configuration>(config)
+      assertEquals("abc-123-configuration-id", config.id)
+      assertEquals(false, config.requiresSessionAuth)
+      assertEquals(7, config.scheduler?.availableDaysInFuture)
+      assertEquals(60, config.scheduler?.minCancellationNotice)
+      assertEquals(120, config.scheduler?.minBookingNotice)
+      assertEquals("", config.scheduler?.confirmationRedirectUrl)
+      assertEquals(false, config.scheduler?.hideReschedulingOptions)
+      assertEquals(false, config.scheduler?.hideCancellationOptions)
+      assertEquals(true, config.scheduler?.hideAdditionalGuests)
+      assertEquals("", config.scheduler?.cancellationPolicy)
+      assertEquals("submit", config.appearance?.get("submit_button_label"))
+      assertEquals(30, config.availability.durationMinutes)
+      assertEquals(15, config.availability.intervalMinutes)
+      assertEquals(15, config.availability.roundTo)
+      assertEquals(AvailabilityMethod.COLLECTIVE, config.availability.availabilityRules?.availabilityMethod)
+      assertEquals(60, config.availability.availabilityRules?.buffer?.before)
+      assertEquals(0, config.availability.availabilityRules?.buffer?.after)
+      assertEquals("", config.availability.availabilityRules?.roundRobinGroupId)
+      assertEquals(5, config.availability.availabilityRules?.defaultOpenHours?.first()?.days?.size)
+      assertEquals("09:00", config.availability.availabilityRules?.defaultOpenHours?.first()?.start)
+      assertEquals("18:00", config.availability.availabilityRules?.defaultOpenHours?.first()?.end)
+      assertEquals("Updated Title", config.eventBooking.title)
+      assertEquals("utc", config.eventBooking.timezone)
+      assertEquals("", config.eventBooking.description)
+      assertEquals(null, config.eventBooking.location)
+      assertEquals(BookingType.BOOKING, config.eventBooking.bookingType)
+      assertEquals(null, config.eventBooking.hideParticipants)
+      assertEquals(null, config.eventBooking.disableEmails)
+      assertEquals(true, config.participants.first().isOrganizer)
+      assertEquals("test@nylas.com", config.participants.first().email)
+      assertEquals("Test", config.participants.first().name)
+      assertEquals("", config.participants.first().timezone)
+    }
+  }
+
+  @Nested
+  inner class CrudTests {
+    private lateinit var grantId: String
+    private lateinit var mockNylasClient: NylasClient
+    private lateinit var configurations: Configurations
+
+    @BeforeEach
+    fun setup() {
+      grantId = "abc-123-grant-id"
+      mockNylasClient = Mockito.mock(NylasClient::class.java)
+      configurations = Configurations(mockNylasClient)
+    }
+
+    @Test
+    fun `listing configurations calls requests with the correct params`() {
+      configurations.list(grantId)
+      val pathCaptor = argumentCaptor<String>()
+      val typeCaptor = argumentCaptor<Type>()
+      val queryParamCaptor = argumentCaptor<ListConfigurationsQueryParams>()
+      val overrideParamCaptor = argumentCaptor<RequestOverrides>()
+      verify(mockNylasClient).executeGet<ListResponse<Configuration>>(
+        pathCaptor.capture(),
+        typeCaptor.capture(),
+        queryParamCaptor.capture(),
+        overrideParamCaptor.capture(),
+      )
+
+      assertEquals("v3/grants/$grantId/scheduling/configurations", pathCaptor.firstValue)
+      assertEquals(Types.newParameterizedType(ListResponse::class.java, Configuration::class.java), typeCaptor.firstValue)
+    }
+
+    @Test
+    fun `creating a configuration calls requests with the correct params`() {
+      val adapter = JsonHelper.moshi().adapter(CreateConfigurationRequest::class.java)
+      val participantCalendarIds = ArrayList<String>()
+      participantCalendarIds.add("primary")
+
+      val configurationAvailabilityParticipant = ConfigurationAvailabilityParticipant.Builder().calendarIds(participantCalendarIds).build()
+
+      val configurationBookingParticipant = ConfigurationBookingParticipant.Builder().calendarId("primary").build()
+
+      val configurationParticipant = ConfigurationParticipant.Builder("test@nylas.com")
+        .availability(configurationAvailabilityParticipant)
+        .booking(configurationBookingParticipant)
+        .name("Test Participant")
+        .isOrganizer(true)
+        .build()
+
+      val configurationAvailability = ConfigurationAvailability.Builder().intervalMinutes(30).build()
+
+      val configurationEventBooking = ConfigurationEventBooking.Builder().title("Test Event Booking").build()
+
+      val participants = ArrayList<ConfigurationParticipant>()
+      participants.add(configurationParticipant)
+
+      val createConfigurationRequest = CreateConfigurationRequest.Builder(
+        participants,
+        configurationAvailability,
+        configurationEventBooking,
+      ).build()
+
+      configurations.create(grantId, createConfigurationRequest)
+
+      val pathCaptor = argumentCaptor<String>()
+      val typeCaptor = argumentCaptor<Type>()
+      val requestBodyCaptor = argumentCaptor<String>()
+      val queryParamCaptor = argumentCaptor<ListConfigurationsQueryParams>()
+      val overrideParamCaptor = argumentCaptor<RequestOverrides>()
+      verify(mockNylasClient).executePost<Response<Configuration>>(
+        pathCaptor.capture(),
+        typeCaptor.capture(),
+        requestBodyCaptor.capture(),
+        queryParamCaptor.capture(),
+        overrideParamCaptor.capture(),
+      )
+      assertEquals("v3/grants/$grantId/scheduling/configurations", pathCaptor.firstValue)
+      assertEquals(Types.newParameterizedType(Response::class.java, Configuration::class.java), typeCaptor.firstValue)
+      assertEquals(adapter.toJson(createConfigurationRequest), requestBodyCaptor.firstValue)
+    }
+
+    @Test
+    fun `updating a configuration calls requests with the correct params`() {
+      val adapter = JsonHelper.moshi().adapter(UpdateConfigurationRequest::class.java)
+      val configId = "abc-123-configuration-id"
+      val config = ConfigurationSchedulerSettings.Builder().minBookingNotice(120).build()
+      val updateConfigurationRequest = UpdateConfigurationRequest.Builder().scheduler(config).build()
+
+      configurations.update(grantId, configId, updateConfigurationRequest)
+
+      val pathCaptor = argumentCaptor<String>()
+      val typeCaptor = argumentCaptor<Type>()
+      val requestBodyCaptor = argumentCaptor<String>()
+      val queryParamCaptor = argumentCaptor<ListConfigurationsQueryParams>()
+      val overrideParamCaptor = argumentCaptor<RequestOverrides>()
+      verify(mockNylasClient).executePut<Response<Configuration>>(
+        pathCaptor.capture(),
+        typeCaptor.capture(),
+        requestBodyCaptor.capture(),
+        queryParamCaptor.capture(),
+        overrideParamCaptor.capture(),
+      )
+      assertEquals("v3/grants/$grantId/scheduling/configurations/$configId", pathCaptor.firstValue)
+      assertEquals(Types.newParameterizedType(Response::class.java, Configuration::class.java), typeCaptor.firstValue)
+      assertEquals(adapter.toJson(updateConfigurationRequest), requestBodyCaptor.firstValue)
+    }
+
+    @Test
+    fun `finding a configuration calls requests with the correct params`() {
+      val configId = "configuration-id"
+      configurations.find(grantId, configId)
+
+      val pathCaptor = argumentCaptor<String>()
+      val typeCaptor = argumentCaptor<Type>()
+      val queryParamCaptor = argumentCaptor<ListConfigurationsQueryParams>()
+      val overrideParamCaptor = argumentCaptor<RequestOverrides>()
+      verify(mockNylasClient).executeGet<Response<Configuration>>(
+        pathCaptor.capture(),
+        typeCaptor.capture(),
+        queryParamCaptor.capture(),
+        overrideParamCaptor.capture(),
+      )
+      assertEquals("v3/grants/$grantId/scheduling/configurations/$configId", pathCaptor.firstValue)
+      assertEquals(Types.newParameterizedType(Response::class.java, Configuration::class.java), typeCaptor.firstValue)
+    }
+
+    @Test
+    fun `destroying a configuration calls requests with the correct params`() {
+      val configId = "configuration-id"
+      configurations.destroy(grantId, configId)
+      val pathCaptor = argumentCaptor<String>()
+      val typeCaptor = argumentCaptor<Type>()
+      val queryParamCaptor = argumentCaptor<ListConfigurationsQueryParams>()
+      val overrideParamCaptor = argumentCaptor<RequestOverrides>()
+      verify(mockNylasClient).executeDelete<DeleteResponse>(
+        pathCaptor.capture(),
+        typeCaptor.capture(),
+        queryParamCaptor.capture(),
+        overrideParamCaptor.capture(),
+      )
+      assertEquals("v3/grants/$grantId/scheduling/configurations/$configId", pathCaptor.firstValue)
+      assertEquals(DeleteResponse::class.java, typeCaptor.firstValue)
+    }
+  }
+}
diff --git a/src/test/kotlin/com/nylas/resources/SessionsTest.kt b/src/test/kotlin/com/nylas/resources/SessionsTest.kt
new file mode 100644
index 00000000..f4e7795c
--- /dev/null
+++ b/src/test/kotlin/com/nylas/resources/SessionsTest.kt
@@ -0,0 +1,103 @@
+package com.nylas.resources
+
+import com.nylas.NylasClient
+import com.nylas.models.*
+import com.nylas.models.Response
+import com.nylas.util.JsonHelper
+import com.squareup.moshi.Types
+import okhttp3.*
+import okio.Buffer
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Nested
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.*
+import java.lang.reflect.Type
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertIs
+
+class SessionsTest {
+  private val mockHttpClient: OkHttpClient = Mockito.mock(OkHttpClient::class.java)
+  private val mockCall: Call = Mockito.mock(Call::class.java)
+  private val mockResponse: okhttp3.Response = Mockito.mock(okhttp3.Response::class.java)
+  private val mockResponseBody: ResponseBody = Mockito.mock(ResponseBody::class.java)
+  private val mockOkHttpClientBuilder: OkHttpClient.Builder = Mockito.mock()
+
+  @BeforeEach
+  fun setup() {
+    MockitoAnnotations.openMocks(this)
+    whenever(mockOkHttpClientBuilder.addInterceptor(any())).thenReturn(mockOkHttpClientBuilder)
+    whenever(mockOkHttpClientBuilder.build()).thenReturn(mockHttpClient)
+    whenever(mockHttpClient.newCall(any())).thenReturn(mockCall)
+    whenever(mockCall.execute()).thenReturn(mockResponse)
+    whenever(mockResponse.isSuccessful).thenReturn(true)
+    whenever(mockResponse.body()).thenReturn(mockResponseBody)
+  }
+
+  @Nested
+  inner class SerializationTests {
+    @Test
+    fun `Session serializes properly`() {
+      val adapter = JsonHelper.moshi().adapter(Session::class.java)
+      val jsonBuffer = Buffer().writeUtf8(
+        """
+        {
+          "session_id": "session-id"
+        }
+        """.trimIndent(),
+      )
+      val session = adapter.fromJson(jsonBuffer)!!
+      assertIs<Session>(session)
+      assertEquals("session-id", session.sessionId)
+    }
+  }
+
+  @Nested
+  inner class CrudTests {
+    private lateinit var mockNylasClient: NylasClient
+    private lateinit var sessions: Sessions
+
+    @BeforeEach
+    fun setup() {
+      mockNylasClient = Mockito.mock(NylasClient::class.java)
+      sessions = Sessions(mockNylasClient)
+    }
+
+    @Test
+    fun `creating a session calls requests with the correct params`() {
+      val adapter = JsonHelper.moshi().adapter(CreateSessionRequest::class.java)
+      val createSessionRequest = CreateSessionRequest.Builder()
+        .configurationId("config-id")
+        .timeToLive(30)
+        .build()
+
+      sessions.create(createSessionRequest)
+
+      val pathCaptor = argumentCaptor<String>()
+      val typeCaptor = argumentCaptor<Type>()
+      val requestBodyCaptor = argumentCaptor<String>()
+      val queryParamCaptor = argumentCaptor<IQueryParams>()
+      val overrideParamCaptor = argumentCaptor<RequestOverrides>()
+      verify(mockNylasClient).executePost<Session>(pathCaptor.capture(), typeCaptor.capture(), requestBodyCaptor.capture(), queryParamCaptor.capture(), overrideParamCaptor.capture())
+
+      assertEquals("v3/scheduling/sessions", pathCaptor.firstValue)
+      assertEquals(Types.newParameterizedType(Response::class.java, Session::class.java), typeCaptor.firstValue)
+      assertEquals(adapter.toJson(createSessionRequest), requestBodyCaptor.firstValue)
+    }
+
+    @Test
+    fun `deleting a session calls requests with the correct params`() {
+      val sessionId = "session-id"
+      sessions.destroy(sessionId)
+
+      val pathCaptor = argumentCaptor<String>()
+      val typeCaptor = argumentCaptor<Type>()
+      val queryParamCaptor = argumentCaptor<IQueryParams>()
+      val overrideParamCaptor = argumentCaptor<RequestOverrides>()
+      verify(mockNylasClient).executeDelete<DeleteResponse>(pathCaptor.capture(), typeCaptor.capture(), queryParamCaptor.capture(), overrideParamCaptor.capture())
+      assertEquals("v3/scheduling/sessions/$sessionId", pathCaptor.firstValue)
+      assertEquals(DeleteResponse::class.java, typeCaptor.firstValue)
+    }
+  }
+}