Scheduling & booking pages

Overview
Scheduling lets other people book time with you — without back and forth. It has four parts: event types (what can be booked), availability (when), booking pages (where booking happens) and connections (which external calendars count).
The key sentence about busy time: a known appointment takes the slot — even without an external calendar. What is in the system counts. A connected calendar adds to that, it does not replace it.
Core tasks
Create an event type. Duration, buffer, notice, location or video link, and who is invited.
Set availability. A schedule describes the regular hours; overrides for individual days take precedence.
Publish a booking page. The page is publicly reachable and shows only genuinely free times.
Route enquiries. A routing form asks questions and then directs to the matching event type or person.
Book resources along. Where a room or device belongs to an appointment, it is booked with it and blocked for others.
Connect calendars. A connection brings external appointments in as busy time.
Fields in detail
The What it does column answers what changes in the system — not what the field is called. The grey name behind the label is the API field: the same thing runs under that name through automation, import and AI tools.
Event type
| Field | Required | Values / format | What it does |
|---|---|---|---|
Name name | yes | text | What can be booked. The invitee reads this name. |
URL slug slug | yes | lowercase letters, digits, hyphens | The part of the public booking URL. Do not change it once shared — every link sent out runs into nothing. |
Description description | no | text | What the invitee reads before choosing. |
Colour color | no | colour value | Colour of the marker in list and calendar. |
Duration durationMinutes | no | minutes, greater than 0 | How long the appointment lasts. It blocks exactly this time — buffers come on top. |
Selectable durations durationOptions | no | list of minute values | Lets the visitor pick between several lengths, 15, 30 and 60 minutes for instance. The default duration is always included, even if it is not listed here. |
Type kind | no | one_on_one, group, collective, round_robin, managed | Who takes the appointment and how many may book. 1:1 is one host per booking, group several invitees on one appointment, collective all hosts at once, round robin distributed in turn, managed set by the team only. This field decides which of the following settings apply at all. |
Seats capacity | no | number, greater than 0 | Group only: how many invitees may take the same appointment. Below 2 it is not a group appointment. |
Location locationKind | no | video_meet, video_teams, video_zoom, video_custom, in_person, phone, ask_invitee, custom | Where the appointment takes place. The video kinds create the link automatically; with ask invitee the guest states it. |
Location details locationConfig | no | object | The addition to the location — address, phone number or your own video link. |
Buffer before bufferBeforeMinutes | no | minutes, 0 or more | Time blocked before the appointment — travel, preparation. |
Buffer after bufferAfterMinutes | no | minutes, 0 or more | The same afterwards. Without buffers appointments sit edge to edge and the first delay topples the day. |
Minimum notice minNoticeMinutes | no | minutes, 0 or more | How short-notice booking may be. The value is in minutes, not hours — one day of notice is 1440, not 24. |
Bookable ahead horizonDays | no | days, greater than 0 | How far into the future booking is allowed. |
Booking horizon type horizonKind | no | rolling (default), fixed range or unlimited | What "bookable until" is measured against: rolling counts days from today, "fixed range" opens exactly one span, "unlimited" allows any date. |
Fixed booking range dateRange | with a fixed range | from date and to date, both inclusive | The one span bookings are possible in — for a trade fair, a campaign week or an office-hours window. An empty value clears the span again. |
Slot increment slotIncrementMinutes | no | minutes, greater than 0 | The grid the free times are offered on. At 15 a 60-minute appointment may also start at 9:15; at 60 only on the hour. This field decides how dense the day gets. |
Daily limit dailyLimit | no | number; 0 or empty = no limit | How many appointments of this type may happen on one day. Once reached, the day disappears from the offer. |
Visibility visibility | no | public, secret | Public appears on booking pages, secret does not — it stays bookable through the direct link. This is restraint, not access control. |
Payment required requiresPayment | no | yes/no | Whether payment is taken before confirmation. |
Price priceAmount | no | amount in cents, 0 or more | What the appointment costs. Kept in cents: 4500 is 45.00 EUR. |
Form questions questions | no | list of questions | What the invitee must state in addition. Every required question costs bookings — ask for what you really need. |
Confirmation page confirmationConfig | no | your own text or a redirect | What the visitor sees after booking: your own thank-you text or a redirect to an address of your choice, a page that counts the conversion for instance. |
Availability scheduleId | no | a schedule | Which schedule provides the bookable hours. Empty means the host's default schedule. |
Hosts hostEmployeeIds | no | employees | Who takes the appointment. Only times the person is genuinely free are offered. Round robin and collective need at least two. |
Resources resourceIds | no | resources | Required rooms and devices. A slot is free only if host and all resources are free. |
Recurrence recurrenceRule | no | {freq: daily/weekly/monthly, interval, count}; empty = single appointment | The invitee books all occurrences in one go. It only happens if every occurrence is free — otherwise none. |
Create lead createLead | no | yes/no | Whether a booking by an unknown visitor creates a lead in the CRM. Without the switch an appointment stays an appointment and the contact is lost. |
Work item per booking workItemKind | no | task, ticket or none | Whether every booking also creates a work item — a task to prepare or a ticket to work on. Empty = no work item. |
Active active | no | yes/no | Off means no longer bookable. Existing bookings remain. |
Brand brandId | no | one of your brands | Under which brand the event type is kept and offered. |
Booking page
| Field | Required | Values / format | What it does |
|---|---|---|---|
Name title | yes | text | The heading of the public page. |
URL slug slug | yes | lowercase letters, digits, hyphens | The part of the public address /public/booking/…. Do not change it once shared. |
Owner type ownerType | no | employee, resource | Whether the page belongs to a person or to a resource. |
Owner ownerId | no | employee or resource | Whose times the page offers. |
Welcome text welcomeText | no | text | What stands at the top of the page. The sentence that explains what the guest is signing up for. |
Image avatarFileId | no | file | The photo or logo of the page. |
Styling branding | no | object | Colours and logo for the white-label appearance. |
Custom domain customDomain | no | domain | Serves the page under your own address. DNS and host routing are an operations step — without it the domain points nowhere. |
Event types eventTypeIds | no | event types | What can be booked on the page. Only active, public types are shown. |
Visibility visibility | no | public, secret | Secret takes the page out of overviews and search engines; it stays reachable. |
Brand brandId | no | one of your brands | Under which brand the page is kept. |
Availability schedule
| Field | Required | Values / format | What it does |
|---|---|---|---|
Name name | yes | text | How the schedule is called in the selection, e.g. "Business hours". |
Owner type ownerType | no | employee, resource | Whether the schedule belongs to a person or to a resource. |
Owner ownerId | no | employee or resource | Whose times it describes. |
Time zone timezone | no | time zone (e.g. Europe/Berlin) | Which zone the hours are meant in. Set wrongly, every offered slot shifts — the most common reason for "the times are wrong". |
Weekly hours weekly | no | time windows "HH:MM"–"HH:MM" per weekday | The regular hours. A day without a window is closed. |
Default schedule isDefault | no | yes/no | The schedule an event type uses when it names none of its own. |
Brand brandId | no | one of your brands | Under which brand the schedule is kept. |
Date override
| Field | Required | Values / format | What it does |
|---|---|---|---|
Schedule scheduleUlid | yes | a schedule | Which schedule the override applies to. |
Date date | yes | YYYY-MM-DD | The one day that deviates from the weekly rule. Overrides always take precedence. |
Time windows intervals | no | pairs "HH:MM"–"HH:MM"; empty = blocked all day | The deviating hours of that day. Leaving it empty means blocked, not "as usual". |
Reason reason | no | text | Why the day deviates. The sentence that answers "why were we closed?" half a year later. |
Routing form
| Field | Required | Values / format | What it does |
|---|---|---|---|
Name name | yes | text | How the form is called in administration. |
URL slug slug | yes | lowercase letters, digits, hyphens | The part of the public form address. |
Description description | no | text | What the visitor reads above the form. |
Fields fields | no | list of key, label, type, required | The questions. The rules refer to their keys — rename a key and the rule stops matching. |
Rules rules | no | list of conditions and target event type | Where visitors are sent. The first rule whose conditions all match wins, so the order is part of the logic. |
Fallback event type fallbackEventTypeSlug | no | slug of an event type | Where visitors go when no rule matches. Without a fallback they end in a dead end. |
Active active | no | yes/no | Whether the form can be answered publicly. |
Brand brandId | no | one of your brands | Under which brand the form is kept. |
Resource (room or device)
| Field | Required | Values / format | What it does |
|---|---|---|---|
Name name | yes | text | What the room or device is called. |
Type kind | no | room, equipment, other | Room, device or other — for grouping the list only. |
Capacity capacity | no | number, greater than 0 | How many people fit in. |
Availability scheduleUlid | no | a schedule | When the resource is bookable at all. Empty means around the clock. |
Location location | no | text | Where the resource is. |
Active active | no | yes/no | Off means no longer bookable alongside. |
Brand brandId | no | one of your brands | Under which brand the resource is kept. |
Calendar connection
Google and Microsoft are connected through their own sign-in dialog and have no input fields. The following fields apply to CalDAV (iCloud, Nextcloud, Fastmail …) and to subscribed iCal/ICS feeds.
| Field | Required | Values / format | What it does |
|---|---|---|---|
Calendar URL url | yes | address of the calendar collection or ICS feed | Where the external appointments come from. For CalDAV the direct collection URL, not the server root. |
User name username | yes (CalDAV) | text | The sign-in on the CalDAV server. |
App password password | yes (CalDAV) | text | The application-specific password — mandatory for iCloud and Fastmail, where the account password does not work. It is stored encrypted and never shown again. |
Label label | no | text | How the connection is called in the list. |
After connecting you choose which calendars count:
| Field | Required | Values / format | What it does |
|---|---|---|---|
Target calendar targetCalendarId | no | a calendar of the connection | Where confirmed appointments are written. Empty means the account's default calendar. |
Busy calendars conflictCalendarIds | no | calendars of the connection | Which calendars additionally block slots. Empty means the target calendar only. |
Pull appointments in syncInbound | no | yes/no | Whether external appointments count as busy time. |
Push appointments out syncOutbound | no | yes/no | Whether booked appointments are written into the external calendar. |
Blocked time has one source. A known appointment takes the slot even without a foreign calendar connected — and so does an appointment from a connected calendar. That is why no double booking can arise while the connection stands.
Settings & permissions
- Event types:
scheduling.event_type.view/.manage - Availability:
scheduling.schedule.view/.manage - Booking pages:
scheduling.booking_page.view/.manage - Appointments:
scheduling.appointment.view_own/.view_any/.manage/.reschedule
Module flag: module.scheduling. Setup walks you through the order.
FAQ & troubleshooting
No free times are shown. Check schedule, notice and buffer — often the notice period is longer than the displayed range.
An appointment from the external calendar is missing. Check the connection. If it fails, what is in the system still counts — so you are not unprotected, but external appointments are missing.
Two bookings on the same slot. Possible if both complete in the same moment. Set a buffer if this happens repeatedly.