https://api.[tenant].getomneo.com/api/v3.
Create a definition
Send aPOST to /appointment-definitions. Only handle, name, duration_minutes, and booking_type are required. Everything else has a default or can be added later.
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
| Field | Type | Notes |
|---|---|---|
handle | string | Required. Unique handle for the definition. Use this, not a slug or key. |
name | string | Required. Display name shown in booking flows. |
duration_minutes | integer | Required. Length of one booking. |
booking_type | enum | Required. instant, approval_required, or walk_in_only. See below. |
description, short_description, long_description | string | Copy for the booking flow. |
icon, image_url | string | Display assets for the booking flow. |
terms_conditions | string | Terms shown to the customer at booking. |
internal_notes | string | Operator-only note. Not customer facing. |
buffer_before_minutes, buffer_after_minutes | integer | Padding held before and after each booking. |
min_lead_minutes | integer | Minimum notice before a slot can be booked. |
max_advance_days | integer | How far ahead a slot can be booked. |
slot_interval_minutes | integer | Spacing between slot start times. |
meta | object | Custom 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_type | Behaviour |
|---|---|
instant | The appointment is confirmed the moment it is booked. |
approval_required | The customer creates a request; an operator confirms or rejects it. |
walk_in_only | No advance booking. Customers join a walk-in queue at the location. |
| Flag | Type | Notes |
|---|---|---|
allow_customer_booking | boolean | Whether customers can self-book. |
allow_walk_in | boolean | Whether walk-in check-in is allowed. |
requires_staff | boolean | Whether each booking has an assigned staff member. |
customer_must_select_staff | boolean | Forces the customer to choose a staff member. Set requires_staff to true as well. |
use_staff_from_location | boolean | Where the eligible staff pool comes from. See Locations and staff. |
max_concurrent_bookings | integer or null | Capacity per slot for non-staff definitions. null means unlimited. For staff-required definitions, capacity is one per staff member per slot. |
allow_waitlist | boolean | Whether customers can join a waitlist. |
allow_queue | boolean | Whether 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.
| Endpoint | Purpose |
|---|---|
POST /appointment-definitions/{definitionId}/normal-hours | Add one weekly entry (day_of_week, available_from, available_until). |
POST /appointment-definitions/{definitionId}/special-hours | Add 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 withlocation_ids and staff_ids:
| Endpoint | Purpose |
|---|---|
POST /appointment-definitions/{definitionId}/locations | Offer the definition at a location. |
POST /appointment-definitions/{definitionId}/staff | Attach a staff member (staff_id, optional is_active). |
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_location | Staff source |
|---|---|
true | Staff assigned to the requested location. |
false | The 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 abooking_questionnaire object on the definition, either inline as a new questionnaire or by referencing an existing questionnaire’s questions.
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.| Event | Target field | Offset fields |
|---|---|---|
| Created | created_target_id | notify_created_offset_days, notify_created_offset_hours |
| Confirmed | confirmed_target_id | notify_confirmed_offset_days, notify_confirmed_offset_hours |
| Completed | completed_target_id | notify_completed_offset_days, notify_completed_offset_hours |
| Cancelled | cancelled_target_id | notify_cancelled_offset_days, notify_cancelled_offset_hours |
| Rejected | rejected_target_id | notify_rejected_offset_days, notify_rejected_offset_hours |
| Reminder | reminder_target_id | notify_reminder_offset_days, notify_reminder_offset_hours |
Visibility conditions
To control which definitions a Profile sees in a customer-facing booking flow, set avisibility_condition: a JsonLogic rule evaluated against the requesting Profile’s attributes.
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.| Flag | Effect |
|---|---|
is_published | When true, the definition is available to booking flows. Create definitions with is_published: false while configuring, then publish. |
is_archived | When true, the definition is retired and excluded from booking flows. |
filter[is_published]=1&filter[is_archived]=0 to fetch only live definitions.
The definition resource
AGET /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.
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.
| Field | Type | Notes |
|---|---|---|
has_booking_questionnaire | boolean | Whether a booking questionnaire is attached. A quick check without inspecting booking_questionnaire. |
normal_hours | array | The weekly opening-hours entries, each { id, day_of_week, available_from, available_until }. |
special_hours | array | The dated overrides, each { id, name, is_repeating, available_from, available_until, start_at, end_at }. |
locations | array | The definition-location attachments, each { id, location_id, is_active }. |
staff | array | The attached staff, each { id, staff_id, is_active }. Populated when the definition uses an explicit staff list. |
booking_questionnaire | object or null | The 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.Create a draft
201 with the generated id. Configure everything else while is_published is false.Attach the booking questionnaire and notifications
Errors
| Status | When |
|---|---|
401 | Missing or invalid bearer token. |
403 | The token lacks the required scope, or the actor lacks permission. |
404 | The definition does not exist, or a nested hours, location, or staff entry does not belong to the definition in the URL. |
422 | Validation failed. Create requires handle, name, duration_minutes, and booking_type; a missing or invalid one returns 422. |
Edge cases and gotchas
max_concurrent_bookings: nullmeans unlimited. Leave itnullfor 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_staffneedsrequires_staff. The customer can only be forced to pick a staff member on a definition that assigns staff, so setrequires_staff: trueas well.- Opening hours are plain local times.
available_fromandavailable_untilare 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
nullvisibility_conditionis excluded. Such a definition never passes the profile-scoped visibility check. Use{"==": [1, 1]}to make it visible to every qualifying Profile.
Related
- Appointments concept
- Working with appointments
- Walk-in queues and waitlists
- Building questionnaires
- Targets
- Add appointment definition API
- Browse appointment definitions API
- Add appointment definition normal hour API
- Add appointment definition staff API
- Browse available appointment slots API
- Browse available appointment staff API
- Browse visible appointment definitions API