Salons, barbers and spas
A platform for hair, beauty and wellbeing businesses has the same shape every time: each shop has staff, sometimes rooms or stations, and a menu of services that take time. Your app owns the menu, prices, customers and payments; Tiempo owns when things can happen.
| In the salon | In Tiempo |
|---|---|
| The shop | An account |
| Stylists, barbers, therapists | Resources, one each |
| Treatment rooms | Resources, one each |
| Identical stations (three nail desks) | One resource with capacity 3 |
| A service | Segments: how long, on which resources |
| Working hours and rotas | Schedules |
| Holidays, sick days, training | Blocks |
Services are segments
Tiempo never needs to know what a “skin fade” is. Your app turns a service into segments when it searches and books: a 45-minute cut is one segment on a barber. A massage is two segments at the same time, the therapist and a room. A course of treatments is several bookings, or a series.
Store the segment pattern with each service in your own database (durations, offsets and which kind of resource), and build the request from it.
“Any stylist” and “a specific stylist”
Give one resource when the customer chose a person, or a list when they didn’t. With a list, search returns who is free at each time, and booking takes the first in your list who still fits, at the moment it books. Put them in the order you’d like them filled: to spread work evenly, or to favour juniors for cheaper services.
If two customers ask for “anyone” at the same time, they get different stylists or one gets a 409. Never the same stylist twice.
When staff take different times
If a cut takes Ann 45 minutes but Bob 30, give the search one duration_minutes and a duration_overrides for whoever differs. Each slot is one possible booking: a start can come back twice, 10:00–10:45 with Ann and 10:00–10:30 with Bob, so group slots by start to show the customer one list of times.
Then book the person they picked, for their length. If someone took them in the meantime you get a 409; offer the next person from the same slot. Other resources in the same search (a chair, a room) run for the same length as whoever it is.
Colour, with time to develop
A colour keeps the stylist for 30 minutes, frees them for 30 while it develops (when they can take a quick cut), then needs them again. Search with two segments and an offset_minutes on the second; each slot lists who is free for each part.
When the same person must do both parts, pick a stylist who appears in both lists and book both segments on them. Searching on one stylist at a time gives you only times that work for that person.
Cleanup and setup time
Set buffer_after_minutes on a resource for cleanup after every booking, and buffer_before_minutes for setup. The customer’s appointment stays 45 minutes; the barber is held for 55. A segment can override them for one service (a bleach needs longer to clear down).
Rotas, time off and late nights
- Alternating weeks: a schedule’s
weekscan list two (or more) weeks that repeat in turn, for every-other-Saturday rotas. - Changing hours from a date: add a new schedule with a later
effective_from; the old one still applies until then. - One different day: a schedule override replaces that date’s hours, for a late night or a half day.
- Time off: a block on the stylist, by dates or times. A block on the account closes the whole shop.
Staff squeezing someone in: when the shop books a client itself, after hours or on a day off, send "conflict_policy": "capacity_only". Working hours and time off are ignored, but it still can’t land on top of another booking. A deliberate double-booking is "allow".
When a change leaves an existing booking outside someone’s hours, Tiempo keeps the booking, marks it conflicted and sends booking.conflicted, so the shop can move it.
The booking flow
- The customer picks a service and, optionally, a stylist.
- Your app turns the service into segments and calls
POST /v1/availabilityfor the days on show. - They pick a time. Hold it with
POST /v1/bookings, then take the deposit or payment. - On payment success,
POST /v1/bookings/{id}/confirm. If they leave, the hold expires. - Reschedules use
/rescheduleand keep the same booking id; cancellations use/cancel. Your webhook hears about every change, including ones made in the shop.
Running a chain? See multi-location businesses. Start building with the quickstart.