# Salons, barbers and spas – Tiempo

> Map a salon or barbershop onto Tiempo: staff and chairs as resources, services as segments, any-stylist bookings, buffers, colour with processing time, rotas and time off.

Source: https://tiempo.one/docs/salons-and-barbers

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.

A massage: therapist and room together

```json
"segments": [
  { "resources": ["res_therapist_lee", "res_therapist_kai"],
    "duration_minutes": 60 },
  { "resources": ["res_room_1", "res_room_2"],
    "duration_minutes": 60 }
]
```

## “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.

Hold with whoever is free

```bash
curl -X POST "$TIEMPO/v1/bookings" \
  -H "Authorization: Bearer $TIEMPO_KEY" \
  -H "Tiempo-Account: $ACCOUNT" \
  -H "Idempotency-Key: apt_881-hold" \
  -H "Content-Type: application/json" \
  -d '{
    "segments": [
      {
        "resources": [
          "res_ana",
          "res_ben",
          "res_cat"
        ],
        "start": "2026-11-16T10:00:00Z",
        "end": "2026-11-16T10:45:00Z"
      }
    ],
    "metadata": {
      "appointment_id": "apt_881",
      "service": "cut-and-finish"
    }
  }'
```

## 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.

Search: 45 minutes, 30 with Bob

```json
{
  "from": "2026-11-16T09:00:00Z",
  "to": "2026-11-16T17:00:00Z",
  "duration_minutes": 45,
  "duration_overrides": { "res_bob": 30 },
  "segments": [
    { "resources": ["res_ann", "res_cat", "res_bob"] }
  ]
}
```

## 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.

Search: apply, develop, finish

```json
"segments": [
  { "resources": ["res_ana", "res_ben"],
    "offset_minutes": 0, "duration_minutes": 30 },
  { "resources": ["res_ana", "res_ben"],
    "offset_minutes": 60, "duration_minutes": 30 }
]
```

Book both parts on Ana

```json
"segments": [
  { "resource": "res_ana",
    "start": "2026-11-16T10:00:00Z", "end": "2026-11-16T10:30:00Z" },
  { "resource": "res_ana",
    "start": "2026-11-16T11:00:00Z", "end": "2026-11-16T11:30:00Z" }
]
```

## 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).

Ten minutes after every booking

```bash
curl -X POST "$TIEMPO/v1/resources" \
  -H "Authorization: Bearer $TIEMPO_KEY" \
  -H "Tiempo-Account: $ACCOUNT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Ana",
    "type": "stylist",
    "buffer_after_minutes": 10
  }'
```

## Rotas, time off and late nights

-   **Alternating weeks:** a schedule’s `weeks` can 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](https://tiempo.one/docs/schedule-overrides) replaces that date’s hours, for a late night or a half day.
-   **Time off:** a [block](https://tiempo.one/docs/blocks) 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.

Two-week rota, alternate Saturdays

```json
"weeks": [
  { "tuesday":  [{ "start": "09:00", "end": "17:30" }],
    "saturday": [{ "start": "09:00", "end": "16:00" }] },
  { "tuesday":  [{ "start": "09:00", "end": "17:30" }] }
]
```

## The booking flow

1.  The customer picks a service and, optionally, a stylist.
2.  Your app turns the service into segments and calls `POST /v1/availability` for the days on show.
3.  They pick a time. Hold it with `POST /v1/bookings`, then take the deposit or payment.
4.  On payment success, `POST /v1/bookings/{id}/confirm`. If they leave, the hold expires.
5.  Reschedules use `/reschedule` and 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](https://tiempo.one/docs/multi-location). Start building with the [quickstart](https://tiempo.one/docs/quickstart).

The machine-readable description is at [/openapi.json](https://tiempo.one/openapi.json). Try calls in [Swagger UI](https://tiempo.one/swagger-ui.html).[Tiempo home](https://tiempo.one/)[Dashboard](https://tiempo.one/app)
