Skip to main content
An Appointment Definition is the bookable service behind every appointment: it sets the duration, booking type, opening hours, the locations and staff it is offered at, capacity, an optional booking questionnaire, notifications, and visibility rules. Create one before customers can book. For the model behind definitions, see the Appointments concept. All endpoints are bearer authenticated and live under https://api.[tenant].getomneo.com/api/v3.

Create a definition

Send a POST to /appointment-definitions. Only handle, name, duration_minutes, and booking_type are required. Everything else has a default or can be added later.
The response is 201 with the saved definition, including its generated id. Use that id on the nested endpoints below and as appointment_definition_id when creating appointments.

Field reference

FieldTypeNotes
handlestringRequired. Unique handle for the definition. Use this, not a slug or key.
namestringRequired. Display name shown in booking flows.
duration_minutesintegerRequired. Length of one booking.
booking_typeenumRequired. instant, approval_required, or walk_in_only. See below.
description, short_description, long_descriptionstringCopy for the booking flow.
icon, image_urlstringDisplay assets for the booking flow.
terms_conditionsstringTerms shown to the customer at booking.
internal_notesstringOperator-only note. Not customer facing.
buffer_before_minutes, buffer_after_minutesintegerPadding held before and after each booking.
min_lead_minutesintegerMinimum notice before a slot can be booked.
max_advance_daysintegerHow far ahead a slot can be booked.
slot_interval_minutesintegerSpacing between slot start times.
metaobjectCustom key/value data.
min_lead_minutes, max_advance_days, the buffers, and the opening hours together define which slots the availability endpoints return.

Booking type and capability flags

booking_type sets how customers book against the definition.
booking_typeBehaviour
instantThe appointment is confirmed the moment it is booked.
approval_requiredThe customer creates a request; an operator confirms or rejects it.
walk_in_onlyNo advance booking. Customers join a walk-in queue at the location.
Independent capability flags layer on top of the booking type.
FlagTypeNotes
allow_customer_bookingbooleanWhether customers can self-book.
allow_walk_inbooleanWhether walk-in check-in is allowed.
requires_staffbooleanWhether each booking has an assigned staff member.
customer_must_select_staffbooleanForces the customer to choose a staff member. Set requires_staff to true as well.
use_staff_from_locationbooleanWhere the eligible staff pool comes from. See Locations and staff.
max_concurrent_bookingsinteger or nullCapacity per slot for non-staff definitions. null means unlimited. For staff-required definitions, capacity is one per staff member per slot.
allow_waitlistbooleanWhether customers can join a waitlist.
allow_queuebooleanWhether the walk-in queue is available.
Set max_concurrent_bookings to null for group services with no fixed cap, such as a class or an event. Leave it unset or null unless the service has a real per-slot limit.

Opening hours

A definition carries two sets of hours, both scoped to the definition itself.
  • Normal hours are the weekly pattern, one entry per day_of_week.
  • Special hours are dated overrides such as public holidays or a one-off change. A special hour takes precedence over the normal hour when a date matches.
Create either inline on the definition or through the nested endpoints. Inline is convenient at create time; the nested endpoints let you add, update, or remove single entries later without rewriting the whole definition. Inline on create:
Add a single normal-hours entry later:
EndpointPurpose
POST /appointment-definitions/{definitionId}/normal-hoursAdd one weekly entry (day_of_week, available_from, available_until).
POST /appointment-definitions/{definitionId}/special-hoursAdd one dated override (name, start_at, end_at, available_from, available_until, is_repeating).
day_of_week accepts MON, TUE, WED, THU, FRI, SAT, or SUN. Times such as available_from are plain local times at the location. Each nested collection also supports GET, and each entry supports PUT and DELETE at .../normal-hours/{id} and .../special-hours/{id}.

Locations and staff

A definition is offered at one or more locations and, when it requires staff, draws from a staff pool. Attach both on create with location_ids and staff_ids:
Manage them individually through the nested endpoints:
EndpointPurpose
POST /appointment-definitions/{definitionId}/locationsOffer the definition at a location.
POST /appointment-definitions/{definitionId}/staffAttach a staff member (staff_id, optional is_active).
Both collections support GET, and each attachment supports PUT and DELETE at .../locations/{id} and .../staff/{id}. Where staff come from depends on use_staff_from_location:
use_staff_from_locationStaff source
trueStaff assigned to the requested location.
falseThe explicit staff attached to the definition through staff_ids or the .../staff endpoint.
When use_staff_from_location is true, you do not attach staff to the definition. Availability draws from the location’s staff for the requested date. When it is false, attach the staff explicitly; their own hours still gate availability.

Booking questionnaire

To capture answers at booking, attach a booking questionnaire. Send a booking_questionnaire object on the definition, either inline as a new questionnaire or by referencing an existing questionnaire’s questions.
Each question needs a mapping_key, which routes the answer to a destination. Reference a reusable Question by question_id, question_handle, or a specific question_version_id. Group questions into pages when the form needs sections. Omneo pins the questionnaire by version, so a booked appointment keeps the form version that was active when it was booked. For how questions and questionnaires are built and how answers are routed, see Building questionnaires and the Questionnaires concept.

Notification targets

A definition can send a notification for each lifecycle event by pointing at a Target and setting an offset. Each event has a target field and a matching pair of offset fields in days and hours.
EventTarget fieldOffset fields
Createdcreated_target_idnotify_created_offset_days, notify_created_offset_hours
Confirmedconfirmed_target_idnotify_confirmed_offset_days, notify_confirmed_offset_hours
Completedcompleted_target_idnotify_completed_offset_days, notify_completed_offset_hours
Cancelledcancelled_target_idnotify_cancelled_offset_days, notify_cancelled_offset_hours
Rejectedrejected_target_idnotify_rejected_offset_days, notify_rejected_offset_hours
Reminderreminder_target_idnotify_reminder_offset_days, notify_reminder_offset_hours
The offset positions the notification relative to the appointment’s scheduled start. A reminder offset of one day sends the reminder 24 hours before the booking. Rescheduling an appointment re-schedules its pending reminders.

Visibility conditions

To control which definitions a Profile sees in a customer-facing booking flow, set a visibility_condition: a JsonLogic rule evaluated against the requesting Profile’s attributes.
Read the definitions a Profile can see from the profile-scoped visibility endpoint:
This returns only published, non-archived definitions whose visibility_condition evaluates to true for that Profile. A null visibility_condition never passes the check, so a definition with null is excluded from the visibility endpoint. To make a definition visible to every qualifying Profile, use a rule that always returns true, such as {"==": [1, 1]}. See Visibility conditions in the concept for how the rule is evaluated.

Publishing a definition

Two flags control whether a definition is live.
FlagEffect
is_publishedWhen true, the definition is available to booking flows. Create definitions with is_published: false while configuring, then publish.
is_archivedWhen true, the definition is retired and excluded from booking flows.
Customer-facing lists filter on both, so query filter[is_published]=1&filter[is_archived]=0 to fetch only live definitions.

The definition resource

A GET /appointment-definitions/{definitionId} returns the full definition wrapped in a data object: every configured field, a has_booking_questionnaire flag, and the loaded normal_hours, special_hours, locations, staff, and booking_questionnaire relations.
Every scalar field you set on create is echoed back: the copy fields, the scheduling fields, booking_type, the capability flags, the notification targets and offsets, visibility_condition, is_published, is_archived, and meta, plus created_at and updated_at in UTC. The relations below are loaded on the read.
FieldTypeNotes
has_booking_questionnairebooleanWhether a booking questionnaire is attached. A quick check without inspecting booking_questionnaire.
normal_hoursarrayThe weekly opening-hours entries, each { id, day_of_week, available_from, available_until }.
special_hoursarrayThe dated overrides, each { id, name, is_repeating, available_from, available_until, start_at, end_at }.
locationsarrayThe definition-location attachments, each { id, location_id, is_active }.
staffarrayThe attached staff, each { id, staff_id, is_active }. Populated when the definition uses an explicit staff list.
booking_questionnaireobject or nullThe attached questionnaire with its questions, null when the definition has none.

End-to-end example: build and publish a definition

Build a definition in a draft state, configure it through the nested endpoints, then publish it once it is complete.
1

Create a draft

The response is 201 with the generated id. Configure everything else while is_published is false.
2

Add opening hours

Repeat for each open day, and add special-hours for holidays.
3

Attach the booking questionnaire and notifications

Attach the booking questionnaire inline or by reference as shown under Booking questionnaire.
4

Publish

Read the definition back to confirm its normal_hours, locations, staff, and booking_questionnaire are all in place before customers can book.

Errors

StatusWhen
401Missing or invalid bearer token.
403The token lacks the required scope, or the actor lacks permission.
404The definition does not exist, or a nested hours, location, or staff entry does not belong to the definition in the URL.
422Validation failed. Create requires handle, name, duration_minutes, and booking_type; a missing or invalid one returns 422.

Edge cases and gotchas

  • max_concurrent_bookings: null means unlimited. Leave it null for group services with no per-slot cap. Set an integer only when a slot has a real limit. It has no effect on staff-required definitions, where capacity is one per staff member per slot.
  • customer_must_select_staff needs requires_staff. The customer can only be forced to pick a staff member on a definition that assigns staff, so set requires_staff: true as well.
  • Opening hours are plain local times. available_from and available_until are local to the location’s timezone and carry no timezone themselves, unlike appointment datetimes, which are stored in UTC.
  • Special hours win. When a date matches both a normal-hours day and a special-hours entry, the special hour takes precedence for that date.
  • Booking questionnaires are pinned by version. A booked appointment keeps the questionnaire version that was active at booking, so editing the form later never rewrites historical answers.
  • A null visibility_condition is excluded. Such a definition never passes the profile-scoped visibility check. Use {"==": [1, 1]} to make it visible to every qualifying Profile.