Slotora for busy salons

Connect your salon's own tools: the Slotora API and webhooks

Your bookkeeper wants the month's bookings in a spreadsheet. Your mailing tool wants new clients. Your website wants to book straight into your diary. Create a key in Settings → API & webhooks, give it to the tool, and choose what it may see. No developer is needed for Zapier or Make, and there is nothing extra to pay.

What salons connect

Zapier
„Webhooks by Zapier” catches every new booking and sends it on — to Google Sheets, Mailchimp, Slack, your CRM.
Make
A „Custom webhook” scenario, or the HTTP module reading your bookings and clients on a schedule.
Your bookkeeper
A key that reads bookings and payments, and nothing else — no client contact details if you hide them.
Your own website
Free times from the API, and a booking made the same way the front desk makes one.

Keys: one per tool, and only what it needs

Only the salon's owner or an admin can create a key. It is shown once — copy it straight into the tool — and Slotora keeps only a fingerprint of it, so nobody can read it back, us included. Give every tool its own key: revoking one stops that tool and nothing else. A key also stops by itself when the person who created it no longer manages the salon.

What a key may do
Read bookingsWhat it allows: Appointments with the client's name, the service, the team member, the price and what was paid; free times.
Read clientsWhat it allows: Names, phone and e-mail, language and marketing consent. Never notes.
Read services and teamWhat it allows: Your service list with prices and lengths, your team and your premises.
Make bookingsWhat it allows: Books a time the salon offers, exactly as the desk would. Off unless you tick it.

The API

Everything is JSON over HTTPS at https://slotora.io/api/v1. Send the key in the Authorization header as „Bearer slt_live_…” (or as X-Api-Key). Dates come back in the salon's own time zone with the offset — 2026-10-13T14:00:00+01:00 — so a spreadsheet shows the time your diary shows. A plain date in a filter (2026-10-13) means that day in the salon's zone. The machine-readable description is at /api/v1/openapi.json.

Endpoints
GET /api/v1/mePermission: anyWhat it answers: Your salon and the key's permissions — the call to test a connection.
GET /api/v1/bookingsPermission: Read bookingsWhat it answers: Bookings from today for 31 days, or between from and to; filter by status, staffId, premisesId, updatedSince.
GET /api/v1/bookings/{id}Permission: Read bookingsWhat it answers: One booking.
GET /api/v1/availabilityPermission: Read bookingsWhat it answers: Free times for serviceId on date (and staffId, premisesId).
POST /api/v1/bookingsPermission: Make bookingsWhat it answers: Books a free time for an existing client (clientId) or a new one (client: name, email, phone).
GET /api/v1/clientsPermission: Read clientsWhat it answers: The client book; filter by createdSince or updatedSince.
GET /api/v1/clients/{id}Permission: Read clientsWhat it answers: One client.
GET /api/v1/servicesPermission: Read services and teamWhat it answers: The service list.
GET /api/v1/staffPermission: Read services and teamWhat it answers: The team.
GET /api/v1/premisesPermission: Read services and teamWhat it answers: Your other premises, if you have more than one address.
curl https://slotora.io/api/v1/bookings?from=2026-10-13&to=2026-10-19 \
  -H "Authorization: Bearer slt_live_YOUR_KEY"

Pages, errors and limits

  • Lists come a page at a time: data, and nextCursor. Pass nextCursor back as cursor until it is null. limit is 1–100 (50 by default).
  • Every error is { "error": { "code": "…", "message": "…" } }: unauthorized (401), insufficient_scope (403), not_found (404), invalid_request (400), slot_taken (409), rate_limited (429).
  • A key may make 120 requests a minute. Past that the answer is 429 with Retry-After.
  • A booking is made by the same code as one at your front desk: the time must be one the salon offers, rooms and chairs are checked, and the guest gets your usual confirmation. Send an Idempotency-Key header and a retry within five minutes returns the booking the first request made instead of a second one.
  • Another salon's ids answer not_found, exactly like ids that do not exist. Every request a key makes is in the salon's request log for 30 days.

Webhooks

Add the address your tool gave you in Settings → API & webhooks and tick what to send. Slotora looks for changes every quarter of an hour, so an event arrives within about 15 minutes of happening. Each address must be https, on the public internet; redirects are not followed.

Events
booking.createdWhen: A booking was made — online, at the desk, by the AI phone or through the API.
booking.updatedWhen: Moved, given to another team member, re-priced, or marked arrived, completed or no-show.
booking.cancelledWhen: Cancelled, by the guest or by the salon.
client.createdWhen: A new client in the client book.
payment.recordedWhen: Money taken on a booking: cash, card, transfer or online.
{
  "id": "evt_…",                  // the same on every retry: ignore one you have seen
  "type": "booking.created",
  "occurredAt": "2026-10-13T09:41:07+01:00",
  "salon": { "id": "…", "timezone": "Europe/London" },
  "data": { …the booking, client or payment, as the API returns it… }
}

Checking that a webhook came from Slotora

Every delivery carries Slotora-Signature: t=<unix time>,v1=<signature>. The signature is an HMAC-SHA256, in hex, of the time, a full stop and the exact body, made with the endpoint's signing secret (whsec_…, shown once when you add it). Recompute it, compare, and refuse anything older than five minutes. Zapier and Make do not need this; your own server should.

import crypto from "node:crypto";

function fromSlotora(secret, header, rawBody) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const expected = crypto.createHmac("sha256", secret)
    .update(`${parts.t}.${rawBody}`).digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
  return fresh && expected.length === (parts.v1 ?? "").length &&
    crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}

When your tool does not answer

  • Any 2xx answer is success. Anything else, or no answer in 10 seconds, is retried after 1 minute, 5 minutes, 30 minutes, then 2, 6, 12 and 24 hours — eight tries in all. Each try is in the endpoint's delivery log.
  • After 15 failed tries in a row, or three days of nothing but failures, the address is switched off and the owner gets a notification. Switch it back on from the same page once it is fixed.
  • „Send a test” sends one signed delivery with sample data, so Zapier or Make can learn the fields without a real client's details.

Zapier, step by step

  1. Catch the hook

    In Zapier, make a Zap whose trigger is „Webhooks by Zapier” → „Catch Hook”, and copy the address it shows.

  2. Add it in Slotora

    Settings → API & webhooks → Webhooks: paste the address, tick what to send, press Add webhook.

  3. Send a test

    Press „Send a test” beside it, then „Test trigger” in Zapier: the sample booking appears with all its fields.

  4. Send it on

    Add the action — a Google Sheets row, a Mailchimp subscriber, a Slack message — and map the fields. To read from Slotora inside a Zap, use „Webhooks by Zapier” → „GET” with the header Authorization: Bearer and your key.

Make, step by step

  1. A custom webhook

    In Make, start a scenario with Webhooks → „Custom webhook”, add one, and copy its address.

  2. Add it in Slotora

    Paste it under Settings → API & webhooks → Webhooks, tick the events, and add it.

  3. Learn the structure

    In Make press „Redetermine data structure”, then „Send a test” in Slotora: Make learns the fields from the sample.

  4. Read on a schedule

    To pull bookings or clients instead, use HTTP → „Make a request” to https://slotora.io/api/v1/bookings with the header Authorization: Bearer and your key, and follow nextCursor.

What never leaves

  • Notes — the client's, the booking's, and the caution field — are never in an answer or a webhook.
  • If you hide clients' phone numbers and e-mail addresses from your team, the API and webhooks hide them too: they come back empty, marked contactsHidden.
  • Every client carries marketing.optedOut. A mailing tool must leave those clients out.
  • Addresses, tax numbers, birthdays, tags, loyalty points and your team's pay are not in the API at all.

Questions

Does the API cost anything?

No. Keys, requests and webhooks are part of Slotora at no charge; the limit is 120 requests a minute per key.

Is there a Slotora app in Zapier's or Make's directory?

Not yet. Use „Webhooks by Zapier” and Make's Webhooks and HTTP modules, as above — they need nothing from a directory.

Can a tool book outside my opening hours?

No. A booking through the API must be a time your salon offers, exactly as on the desk's own picker. Booking outside the rules stays a front-desk decision.

Who can create a key?

The salon's owner or an admin, in the browser. In the app (from its next version) you can see your keys, webhooks and the request log.

How quickly does a webhook arrive?

Within about 15 minutes of the change. Slotora checks for changes every quarter of an hour.

The rest of this product

The other pages about Slotora for busy salons.

Set up tonight, take bookings tomorrow

Register, add your services and each colleague's hours, and your booking page is live. No card, no contract, no notice period.

Everything Slotora does for a salon

Open a salon account

May we measure which pages actually help? “Accept all” also lets us measure our own adverts.

What exactly does this mean?

We'd like to use Google Analytics to see which pages help and which don't, and to remember which poster, flyer or message of ours — or which salon's recommendation — brought you here. Accept all also allows a Meta advertising pixel, so we can tell which of our own adverts brought a salon that signed up — and if you create an account, our server sends Meta your email address scrambled (hashed), never as readable text, with your IP address, your browser's details and Meta's own cookie ids — never your name — purely so it can recognise that the sign-up came from an advert. None of this runs on a salon's own booking page. Everything the service itself needs works either way. Cookie Policy