Avita/Developers

Developers

Avita runs on one HTTP API — the same one the dashboard, the booking site, and the front-desk iPad use. This page covers how it authenticates, how it answers, and how to be told when something happens.

Overview

The API is served from api.avita.salon over HTTPS only. It speaks JSON in both directions, and it is multi-tenant: every authenticated request is bound to exactly one salon by its credentials, and the database enforces that boundary independently of the application layer.

A readiness probe is public and unauthenticated, which makes it a convenient reachability check from your own monitoring:

curl https://api.avita.salon/readyz
# 200 {"status":"ok"}   — API, database and cache all reachable
# 503                   — a dependency is down

Authentication

Staff sessions use short-lived bearer access tokens with rotating refresh tokens. Sign in with an email and password to receive a pair:

curl -X POST https://api.avita.salon/auth/login \
  -H 'content-type: application/json' \
  -d '{"email":"owner@example.com","password":"..."}'

Send the access token as a bearer credential on every subsequent request, and exchange the refresh token at POST /auth/refresh when it expires — refresh rotates, so the old token stops working the moment a new one is issued.

curl https://api.avita.salon/appointments \
  -H 'authorization: Bearer <access-token>'

There are three separate credential families, and they are not interchangeable: staff (dashboard and mobile), client (the booking portal, one salon’s client), and kiosk (a front-desk iPad, paired to a location with a one-time code so a shared device never holds a person’s login).

Authentication and password endpoints are rate-limited per IP. Expect 429 under abuse and back off rather than retrying immediately.

Conventions

Successful responses return the resource, or 201 with the created object. Failures share one envelope, so a client can handle them uniformly:

{
  "error": true,
  "code": "STRIPE_SIGNATURE_MISSING",
  "message": "Missing Stripe-Signature header"
}

Money is always in integer cents — never floats. Timestamps are ISO 8601 in UTC; the salon’s own timezone is a property of its location and is applied for display, not storage. Identifiers are UUIDs.

The public booking surface

One group of endpoints is deliberately unauthenticated: the ones a salon’s own clients use to book. They are scoped by the salon’s slug in the path, and they expose only what a prospective client may see — the menu, the staff who can be booked, and open times.

GET  /public/:slug                     salon profile, services, staff
GET  /public/:slug/availability        open slots for a service and date
GET  /public/:slug/availability/week   a week of availability at once
POST /public/:slug/appointments        create a booking
POST /public/:slug/waitlist            join the waitlist

This is what powers book.avita.salon, and it is the surface to build against if you want a salon’s booking flow inside your own site or app.

Webhooks

Avita receives signed webhooks from the services it integrates with — Stripe for payments and Connect account changes, Twilio for message delivery and inbound texts, SendGrid for email events. Each receiver verifies the sender’s signature before doing any work, and each is idempotent: a redelivery of an event already processed is acknowledged and ignored rather than applied twice.

POST /webhooks/stripe            payments, refunds, subscriptions, Connect
POST /webhooks/twilio/status     SMS delivery status
POST /webhooks/twilio/inbound    inbound SMS from clients
POST /webhooks/sendgrid          email delivered, bounced, dropped, spam

Outbound webhooks — Avita notifying your system when a booking is made or a sale closes — are on the roadmap and not available yet. If that’s what you need, say so in the note below; it helps us prioritise the event list.

Getting access

The API is live and is what every Avita client application already runs on, but a self-serve partner programme with public API keys isn’t open yet — today, access is granted per integration. There is no published OpenAPI specification at this time.

If you’re building something for a salon on Avita, or an integration you’d like every salon to have, email developers@avita.salon with what you want to build and which of the surfaces above you expect to use. If you’re a salon rather than a developer, the documentation is the better starting point.