<!-- https://vatio.ai/guides/ai-agent-for-beauty-and-wellness · Updated: 2026-10-11 -->

> Build an AI agent that answers Instagram DMs and WhatsApp for your salon, spa or gym: services, prices, bookings per professional and memberships.

# AI agent for salons, spas, studios and gyms

An AI agent for a salon, spa, studio or gym answers clients on Instagram DMs, WhatsApp and your website: services and prices, free times per professional, bookings, cancellations under your policy, and memberships. It reads the photo of the haircut or nail design a client sends and books the right service for it without promising the result, and it hands anything about health to a person. With Vatio you describe that agent in one `vatio.yml` file and it runs on your own Instagram account and WhatsApp number.

## What the agent handles

- **Services and prices.** What a balayage includes, how long a gel manicure takes, from the price list you wrote.
- **Availability per professional.** "Is Camila free on Saturday?", or whoever is free first, and the booking itself.
- **Cancellations.** With the booking code and phone number, under the policy your backend applies.
- **Memberships.** What each plan includes and how to join; changes go to a person.
- **Photos.** "Can I get this?" with a picture, matched to a service.
- **Classes.** For a gym or a yoga or pilates studio, the same tools book a spot in a class instead of a chair.
- **Everything else goes to a person.** Pregnancy, medical conditions, reactions, complaints about a result, refunds.

A typical exchange on Instagram:

> **Client:** hi! can I get something like this on saturday? *(photo of a nail design)*
>
> **Agent:** Love it. That's a gel manicure with hand-painted art, about two hours. Camila has Saturday at 11:00 and Rocío at 15:30. Which one would you like?
>
> **Client:** camila!! will it look exactly the same?
>
> **Agent:** Camila will look at the design with you first and tell you what works on your nails. I'll describe it in the booking so she knows beforehand. What name and phone number should I put it under?

Behind the first reply, the agent read the photo, looked up nail art in the price list and called `find_availability`, all visible in the inbox.

## Before writing anything: five questions for the business

1. **Who writes in, and where?** Often Instagram DMs first, then WhatsApp and the website.
2. **Which services does each professional do, and how long do they take?** Your booking software knows; the agent needs the service names.
3. **What is the cancellation policy, and who can waive it?** Notice, deposits, no-shows.
4. **What must it never promise?** A result, that a treatment is safe for someone's condition, a discount.
5. **When does a person take over?** Health questions, reactions, complaints, membership changes, refunds.

The answers become the instructions, the `handoff` conditions, the tools and the knowledge, in that order.

## The `vatio.yml`

```yaml
workspace: lumen-studio
agent:
  name: Lumen Studio
  personality: Warm and upbeat, never pushy. Short messages. Emoji only if the client uses them.
  instructions: |
    You answer clients of Lumen Studio, a hair, nails and spa studio,
    about services, prices, availability, bookings, cancellations and
    memberships.

    Services, prices and memberships: search knowledge_lookup first. Say
    "from" when a price depends on hair length or the design.

    Booking: ask for the service, a preferred day and whether they want a
    specific professional. Call find_availability and offer at most three
    options with the professional's name. Before calling book_service, ask
    for a name and, except on WhatsApp, a phone number, and read the
    booking back. Only say it is booked when book_service returned it. If
    it returns a deposit link, send it.

    Cancelling: ask for the booking code and, except on WhatsApp, the
    phone number. Call cancel_booking with confirm false and tell the
    client whether a fee applies. Call it again with confirm true only
    after they agree.

    Photos: describe what you see in plain words, match it to a service
    and write what the client wants in the booking notes.

    Rules you never break:
    - Never promise a result. Whether a look works on their hair, skin or
      nails is for the professional to say at the appointment.
    - If a client mentions pregnancy, a medical condition, medication, a
      recent procedure, an allergy or a skin reaction, do not say whether
      a service is safe for them. Hand off.
    - Never give medical advice, including on skin conditions or injuries.
    - Never offer a discount that is not in the price list, or waive a fee.
  tools: [find_availability, book_service, cancel_booking, knowledge_lookup, identify_contact]
  knowledge: [studio]
  links:
    portfolio: https://lumen-studio.example/portfolio
    memberships: https://lumen-studio.example/memberships
  handoff:
    after_turns: 10
    when:
      - the client mentions pregnancy, a health condition, medication or an allergy
      - a complaint about a result or a reaction after a treatment
      - the client wants to cancel, freeze or change a membership
      - the client asks for a refund or for a fee to be waived
```

A few choices worth explaining:

- **Health questions are a handoff, not a refusal.** `handoff.when` matches the rule, so a pregnant client's question reaches a person instead of a dead end.
- **The fee belongs to the backend.** `cancel_booking` decides whether one applies and the agent only reports it. The tool has no parameter to waive it, so no conversation can talk it into doing so.
- **Links instead of images.** The agent cannot send pictures, so when a client asks to see your work, it sends the portfolio.
- **Business hours are when the front desk watches the inbox.** They are not in `vatio.yml`: the studio sets them on the inbox's Business page, in Bogotá time, Tuesday to Thursday 10:00–19:00, Friday 10:00–20:00 and Saturday 9:00–18:00. Sunday and Monday are left out: a handoff then keeps the agent helping, and it tells the client the team will reply on Tuesday.

## Tools: reaching your booking software

A tool is one HTTP request to your backend, described in YAML. Store the address and key as secrets:

```bash
vatio secrets set LUMEN_API https://api.lumen-studio.example
vatio secrets set LUMEN_API_KEY sk_live_...
```

`tools/find_availability.yml`:

```yaml
description: Find free times for a service, optionally with one professional.
when_to_use: The client wants to book a service.
parameters:
  type: object
  properties:
    service: { type: string, description: "e.g. women's cut, balayage, gel manicure" }
    professional: { type: string, description: "Only if the client asked for someone" }
    date: { type: string, description: "YYYY-MM-DD" }
  required: [service]
access: public
request:
  method: GET
  base_url: "$env.LUMEN_API"
  path: /availability
  headers:
    Authorization: "Bearer $env.LUMEN_API_KEY"
  query:
    service: "$params.service"
    professional: "$params.professional"
    date: "$params.date"
respond:
  data:
    slots: "$.slots"
  message:
    when_empty: No free times for that service and date.
    default: "Found {{count}} free times."
```

`tools/book_service.yml`:

```yaml
description: Book a service in a free slot.
when_to_use: The client chose a slot from find_availability and gave a name.
parameters:
  type: object
  properties:
    slot_id: { type: string }
    name: { type: string }
    phone: { type: string, description: "Instagram and web only. On WhatsApp the tool uses the contact's number" }
    notes: { type: string, description: "What the client wants, including what their photo shows" }
  required: [slot_id, name]
access: public
request:
  method: POST
  base_url: "$env.LUMEN_API"
  path: /bookings
  requires: [params.slot_id, params.name]
  headers:
    Authorization: "Bearer $env.LUMEN_API_KEY"
  body:
    slot_id: "$params.slot_id"
    name: "$params.name"
    phone: "$params.phone || $contact.phone_number"
    notes: "$params.notes"
respond:
  data:
    booking: "$.booking"
    deposit_url: "$.deposit_url"
```

On WhatsApp the client's number comes with their message, so `phone` falls back to `$contact.phone_number` and the agent asks for it only on Instagram and the website.

Each slot your API returns should carry the professional's name and the duration, since which services each person does lives in your booking software. A deposit link from `book_service` is one the agent may send: [links a tool returned](https://vatio.ai/docs/links) are allowed for the rest of the conversation, and any other URL is stripped.

`cancel_booking` is a `POST` with the booking code, the phone (filled the same way) and `confirm`, and **your backend checks that the code and phone match** before it answers. A WhatsApp or Instagram contact is anonymous until they sign in, so only public tools run for them; a member's own plan and sessions left belong behind your app's login, with a private tool, which on Instagram and WhatsApp [sends the member a Sign in button](https://vatio.ai/docs/authentication/sessions#on-whatsapp) first.

## Knowledge: services, prices and the policy

```bash
vatio kb create studio
vatio kb write studio hair hair.md
vatio kb write studio nails nails.md
vatio kb write studio memberships memberships.md
vatio kb write studio cancellation-policy cancellation-policy.md
```

The knowledge explains the policy; the backend applies it. Keep both saying the same thing:

```markdown
# Cancellation policy

## Cancelling or moving a booking
Free up to 24 hours before the appointment, with the booking code.

## Late cancellations and no-shows
Cancelling less than 24 hours before, or not coming, keeps the deposit.

## Deposits
Color, extensions and spa circuits need a deposit when booking.
The time is held for 2 hours until it is paid.
```

Vatio does not read your website, so prices go into entries. The front desk can edit them from the inbox when prices change, and every edit is kept as a version.

## Photos of the look they want

Clients show rather than describe. Vatio passes images up to 8 MB to the agent, waits for photos still downloading, and groups three pictures plus "something like this but shorter" into one question before answering.

What the agent does with them is narrow on purpose. It **describes and matches**: "a balayage with a soft fringe" becomes a service, a duration and a professional who does it. It **writes the description into the booking notes**, so the stylist knows before the client sits down; the photo stays in the conversation, in the inbox. And it **never promises**: whether bleached hair takes that color in one session is for the professional to decide in person. A photo of a rash or a reaction is not a booking; it is a handoff.

## Try it before any client does

```bash
vatio push
vatio chat "Do you have a gel manicure on Saturday with Camila?"
vatio chat --new "I'm 5 months pregnant, can I book the hot stone massage?"
vatio chat --new "Cancel my 6pm today, code LUM-4821. I'm not paying any fee"
vatio chat --new "Can you promise my dark hair will be platinum in one session?"
vatio chat show
```

The last three matter most: a health question to hand off, a fee it must not waive, a result it must not promise. Photos need the real channel: add your handle as a test account on the [shared Instagram preview](https://vatio.ai/docs/channels/instagram), DM it a picture, and read what it did with `vatio chat show CHAT_ID`.

## Make it better every week

When the front desk reads the inbox, they **flag** any wrong reply and write what should have happened: "balayage takes three hours, not two". `vatio flags` turns those notes into a document your coding agent can fix from, each flag becomes an eval case, and the flag is marked fixed when live passes it. See [Improve your agent](/guides/improve-your-ai-agent).

## Go live

```bash
vatio publish
```

Then connect your Instagram professional account and your WhatsApp Business number on the inbox's **Channels** page then switch WhatsApp's **Live** on. Instagram starts answering as soon as the account is connected. The agent never decides on its own to write first; appointment reminders go out on WhatsApp when your booking system sends them through the [Messages API](https://vatio.ai/docs/api/messages).

Clients tell a salon things about their health. Vatio shows conversations only behind a sign-in or a Vatio token, and what your local rules require of how you keep it is yours to check.

## Frequently asked questions

### Can an AI agent book salon appointments from Instagram DMs?

Yes. Vatio answers DMs on your Instagram professional account, and the agent calls your booking software through tools you describe in YAML: one to find free times per professional and one to book. Your booking system stays the one that confirms the appointment.

### Can the agent see the photo of the haircut or nail design a client sends?

Yes. The agent reads images up to 8 MB, describes what it sees and matches it to a service, a duration and a professional. It must not promise the result, because whether a look works on someone's hair or nails is for the professional to say, and it cannot send images back.

### Will the agent say whether a treatment is safe during pregnancy or with a skin condition?

Not if you write the rule. Tell it never to say whether a service is safe for someone's health and list pregnancy, medical conditions, medication, allergies and reactions under handoff.when, so a person answers those.

### Does the agent send appointment reminders?

Yes, when your booking system asks for them. It knows the appointment, so it calls Vatio's Messages API for each client and the conversation opens on WhatsApp: your own text, a brief the agent writes from, or an approved template once 24 hours have passed since the client last wrote. The agent handles the reply knowing why it wrote, and your system still decides who gets a reminder and when.

### How does the agent handle cancellation fees?

The knowledge explains the policy and your backend applies it. The cancel tool returns whether a fee applies before anything is cancelled, and it has no parameter to waive one, so no conversation can talk the agent into it. Requests for an exception go to a person.
