Services and availability

Services, multi-resource requirements, schedules and how slots are computed.

Services

A service is what the customer books.

FieldMeaning
duration_minLength of the service
step_minGrid for start times (every 15, 30 minutes…)
buffer_before_min / buffer_after_minCleanup or preparation time blocked around the booking
price_cents, currencyPrice shown by the bot (always from the database)
deposit_centsPix deposit required to confirm
lead_time_minMinimum notice (for example 60 minutes)
max_advance_daysHow far ahead customers can book
window_modeThe slot is a fixed window (deliveries: 14:00–16:00)
fulfillment_modescheduled (default, with a time slot) or queue (dispatch by queue, no fixed time)
intake_formJSON Schema of extra data to collect (insurance, address…)
requirementsWhich resources the service needs at the same time

Window or dispatch: two fulfillment modes

Every service defines how the booking is fulfilled (fulfillment_mode):

  • scheduled (the default): the booking occupies a known time range — a fixed slot or, with window_mode, a window (deliveries from 14:00 to 16:00, with capacity per zone).
  • queue (dispatch, for water, gas or on-demand delivery): the booking has no fixed time — it joins a courier's backlog queue. The engine assigns it to the courier with the fewest active tasks, and each courier has a cap on active tasks at a time, enforced in the database. The queue uses the same states as a booking: pending → accepted → started → completed (or failed).

So the same delivery business can offer scheduled windows, immediate dispatch, or both.

Requirements

A requirement says: from this group, I need this many units. A service can have several; a slot exists only if all of them are free.

{
  "name": "Laser hair removal",
  "duration_min": 45,
  "buffer_after_min": 10,
  "requirements": [
    { "resource_group_id": "grp_professionals", "units": 1 },
    { "resource_group_id": "grp_lasers", "units": 1 },
    { "resource_group_id": "grp_rooms", "units": 1 }
  ]
}

With two professionals but only one laser, Wagend will never offer two overlapping laser sessions.

Advanced options:

  • units: "party_size" — consume as many units as people (restaurants, classes).
  • offset_min / duration_min on a requirement — use a resource for part of the service only (for example the wash basin during the last 15 minutes of a hair color).

Schedules

Each resource has a schedule: weekly rules in the resource's time zone plus overrides for specific dates (closed, or special hours).

{
  "tz": "America/Sao_Paulo",
  "weekly": { "tue": [["09:00", "19:00"]], "sat": [["08:00", "12:00"], ["13:00", "16:00"]] },
  "overrides": [{ "date": "2026-12-24", "ranges": [["09:00", "13:00"]] }, { "date": "2026-12-25", "closed": true }]
}

How slots are computed

  1. Expand the schedules for the requested range, in each resource's time zone.
  2. Remove active bookings and holds (plus buffers) and manual blocks.
  3. Cut into candidate slots using the service duration and step.
  4. Apply lead time, max advance, cutoff rules and party size.
  5. Cross all requirements, trying group members according to the assignment strategy.
  6. Return a short, ordered list.

When nothing is available, the response includes unavailable_reason (closed, no_staff, no_equipment, no_space, lead_time, max_advance, cutoff, full) so the bot can explain why.