Skip to content

Salon Booking

Build a salon booking system with stylist assignment, service-based durations, and deposit handling.

Domain Mapping

Salon ConceptAvailEngine ConceptHow to Set Up
SalonBusinessCreate one business per salon
StylistResourceresource_type: "staff", capacity_min: 1, capacity_max: 1
Service (haircut, color)ServiceDuration + price per service
AppointmentBookingservice_id → auto-sets duration, start_time = appointment time
Walk-in listWaitlistClients waiting for a cancellation

Step-by-Step Setup

1. Create the Business

bash
curl -X POST https://api.availengine.com/v1/developer/businesses \
  -H "Authorization: Bearer YOUR_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Glamour Studio",
    "business_type": "salon"
  }'

2. Add Stylists (Resources)

bash
curl -X POST https://api.availengine.com/v1/manage/resources \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Anna", "resource_type": "staff", "capacity_min": 1, "capacity_max": 1, "section": "Senior Stylists", "display_order": 1}'

curl -X POST https://api.availengine.com/v1/manage/resources \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Maria", "resource_type": "staff", "capacity_min": 1, "capacity_max": 1, "section": "Senior Stylists", "display_order": 2}'

curl -X POST https://api.availengine.com/v1/manage/resources \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Elena", "resource_type": "staff", "capacity_min": 1, "capacity_max": 1, "section": "Junior Stylists", "display_order": 3}'

3. Add Services

Define services with duration and price. The duration drives how long the stylist is blocked:

bash
# These are stored in your services table — create them via your database or a custom endpoint.
# Example service records:
# { "name": "Haircut & Blow-dry", "duration_minutes": 45, "price_cents": 3500 }
# { "name": "Full Color", "duration_minutes": 120, "price_cents": 8000 }
# { "name": "Balayage", "duration_minutes": 180, "price_cents": 15000 }
# { "name": "Blow-dry", "duration_minutes": 30, "price_cents": 2000 }

Service Durations

Services are optional. If you don't use services, set a default_slot_duration_minutes and all bookings use that duration. With services, each service has its own duration and the slot auto-sizes.

4. Set Operating Hours

bash
curl -X PUT https://api.availengine.com/v1/manage/hours \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "hours": [
      {"day_of_week": 0, "is_open": false},
      {"day_of_week": 1, "is_open": false},
      {"day_of_week": 2, "is_open": true, "open_time": "09:00", "close_time": "18:00", "last_booking_time": "16:30"},
      {"day_of_week": 3, "is_open": true, "open_time": "09:00", "close_time": "18:00", "last_booking_time": "16:30"},
      {"day_of_week": 4, "is_open": true, "open_time": "09:00", "close_time": "20:00", "last_booking_time": "18:30"},
      {"day_of_week": 5, "is_open": true, "open_time": "09:00", "close_time": "20:00", "last_booking_time": "18:30"},
      {"day_of_week": 6, "is_open": true, "open_time": "09:00", "close_time": "14:00", "last_booking_time": "12:30"}
    ]
  }'

Late Night Hours

Many salons stay open late on Thursdays and Fridays. Set last_booking_time so clients can't start a 2-hour color at 18:30 when you close at 20:00.

5. Configure Booking Settings

bash
curl -X PATCH https://api.availengine.com/v1/manage/settings \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "default_slot_interval_minutes": 15,
    "default_slot_duration_minutes": 60,
    "booking_window_days": 90,
    "min_notice_hours": 4,
    "max_capacity": 1,
    "default_deposit_amount_cents": 20
  }'
SettingWhy This Value
slot_interval_minutes: 15Appointments start every 15 minutes
booking_window_days: 90Clients book months ahead for weddings/events
min_notice_hours: 4Stylists need notice before a cancellation
max_capacity: 1One client per stylist at a time

6. Check Availability

bash
# Check Anna's availability for a specific date
curl "https://api.availengine.com/v1/availability/YOUR_BUSINESS_ID?date=2026-06-14&resource_id=ANNA_ID&duration_minutes=60"

7. Book an Appointment

bash
curl -X POST https://api.availengine.com/v1/bookings/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "business_id": "YOUR_BUSINESS_ID",
    "resource_id": "ANNA_ID",
    "service_id": "HAIRCUT_SERVICE_ID",
    "customer": {
      "first_name": "Sophia",
      "last_name": "Papadopoulos",
      "phone": "+306981234567",
      "email": "sophia@example.com"
    },
    "booking_date": "2026-06-14",
    "start_time": "10:00",
    "capacity": 1
  }'

Salon-Specific Patterns

Buffer Time Between Clients

Salon services don't always end exactly on time. Add buffer by using a duration_minutes that includes cleanup:

Actual service: 45 min haircut
Buffer: 15 min (cleanup, consult next client, sanitize station)
Set service.duration_minutes = 60

Or use the default_slot_interval_minutes setting — if your slot interval is 30min and a service is 45min, the next slot starts at the next 30min mark, giving you 15min buffer.

Deposit Per Service

Charge a percentage deposit based on the service price:

bash
# Service: Balayage (€150). Set deposit to 20% = €30
curl -X PATCH https://api.availengine.com/v1/manage/settings \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"default_deposit_amount_cents": 30}'

The deposit is charged when the client books. If they cancel within the cancellation window, it's refunded. If they no-show, you keep it.

Recurring Clients

Clients who come every 6 weeks for color. Use webhooks to trigger reminders:

  1. Client books a color appointment
  2. booking.completed webhook fires
  3. Your system schedules a reminder email 5 weeks later
  4. Client rebooks via a link in the email

Stylist Specialization

Some stylists only do cuts, others only do color. Handle this by:

  • Creating sections: "Colorists", "Cut Specialists"
  • In your frontend, filter resources by section based on the selected service
  • Or create separate businesses per specialization (e.g., "Glamour Studio — Color")

Multiple Services Per Visit

A client wants a cut AND a color. Two approaches:

Option A: Book two separate appointments (one for each service) — gives more flexibility if different stylists handle each.

Option B: Create a combined service ("Cut + Color, 165 min, €115") — simpler booking flow for the client.

Widget Integration

js
const client = new AvailEngine('avail_live_YOUR_KEY');
// 1. Load services for the salon
// 2. When client picks a service, set durationMinutes from service.duration_minutes
// 3. Show availability filtered by that duration
// 4. Optionally let client pick a specific stylist

async function getSlotsForService(businessId, date, service) {
  return client.availability(businessId, {
    date,
    durationMinutes: service.durationMinutes,
    capacity: 1
  });
}

Dashboard Tips

  • Staff bookings: Use the staff booking form for phone/walk-in appointments — no deposit required
  • Resources tab: See which stylists are active. Disable a stylist on vacation with is_active: false
  • Notes: Use staff_notes to track client preferences ("likes it shorter in summer", "allergic to ammonia-based color")
  • Google Calendar: Connect each stylist's Google Calendar so their personal appointments block their work schedule

Next: Clinic guide → | Back to Restaurant →

Released under the MIT License.