Let AI agents book with your business

An MCP server, a REST API and signed webhooks, with keys the owner controls and the salon's rules checked on every booking.

MCP server

The Model Context Protocol lets an AI assistant call Cadenspot tools directly: Streamable HTTP and JSON-RPC 2.0 at one URL, and each key acts for one business only.

POSThttps://cadenspot.com/api/mcp

Tools

A key only sees and calls the tools its scopes allow.

Scope availability:read

  • list_event_typesThe services clients can book, with length, price, options, policy and preparation.
  • list_staffThe stylists a client can ask for, for one service.
  • get_available_slotsOpen times for one service, up to 14 days per call, from hours, bookings and connected calendars.

Scope bookings:read

  • get_bookingOne booking by its reference, with its status and what can still change.
  • find_client_bookingsA client's appointments, found by phone or email.
  • get_client_contextA short card on the caller: visits, no-shows, last service, upcoming appointments.

Scope bookings:write

  • intakeStart here: pass the client's own words; the server picks the service and the next step.
  • propose_slotsUp to 3 times that fit the client's wish; when a phone or email is known, the first is held for 10 minutes.
  • hold_slotHolds a time for up to 10 minutes while the client confirms.
  • release_holdFrees a held time.
  • create_bookingBooks a time, re-checked against the rules and live calendars; the same stylist is never booked twice for it.
  • reschedule_bookingMoves a booking to a new time; both sides get an updated invitation.
  • escalate_to_ownerHands refunds, complaints and anything unusual to the owner.
  • join_waitlistAdds the client to the waitlist when no time suits them.

Scope bookings:cancel

  • cancel_bookingCancels once the agent passes confirmed: true (after the client's yes) and offers nearby times to rebook.

Scope bookings:approve

  • decide_requestAccepts or declines a booking request; needs the bookings:approve scope.

Connect your assistant

Add this to your MCP client's config (Claude Code reads it from .mcp.json) and replace YOUR_API_KEY with a key from Dashboard → Settings → API keys. Other clients need the same URL and Authorization header.

.mcp.json
{
  "mcpServers": {
    "cadenspot": {
      "type": "http",
      "url": "https://cadenspot.com/api/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}

REST API v1

For code that isn't an MCP client: plain HTTPS and JSON, with the same keys and scopes. Send the key as a Bearer token.

  • GET/api/v1/services

    The business and its bookable services, with prices from the owner's settings.availability:read
  • GET/api/v1/availability

    Open times for one service, computed live, up to 14 days.availability:read
  • POST/api/v1/bookings

    Books a time. Send an Idempotency-Key header so a retry never books twice.bookings:write
  • GET/api/v1/bookings/:id

    One booking and the actions still allowed.bookings:read
  • PATCH/api/v1/bookings/:id

    Cancel (bookings:cancel) or reschedule (bookings:write) a booking.bookings:cancelbookings:write

Errors come back as JSON with a stable error code and a message: 401 for a bad key, 403 when the key lacks the scope, 429 at the rate limit.

A first call

curl
curl https://cadenspot.com/api/v1/services \
  -H "Authorization: Bearer YOUR_API_KEY"

Webhooks

Get told when something happens. The owner adds an endpoint in Dashboard → Settings → Webhooks and picks the events.

  • booking.createdA booking is confirmed.
  • booking.requestedA booking waits for the owner's approval.
  • booking.rescheduledA booking moved to a new time.
  • booking.cancelledA booking was cancelled.
  • booking.declinedThe owner declined a request, or it expired.
  • booking.reminderAbout 24 hours before the appointment.
  • booking.no_showThe owner marked the client as a no-show.
  • escalation.createdAn agent handed a conversation to the owner.
  • waitlist.slot_openedA time opened up and waitlisted clients were told.
  • rebook.dueA client is due to book their next visit.

Signed payloads

Every delivery carries x-veyracal-signature (v1= then a hex HMAC-SHA256 of the timestamp, a dot and the raw body), x-veyracal-timestamp (Unix seconds), x-veyracal-event and x-veyracal-delivery. Before comparing the HMAC, reject the delivery if the timestamp or the signature is missing or malformed, or if the timestamp is more than 300 seconds from your clock; then compare in constant time and dedupe on the delivery id. A failed delivery is tried up to 5 times in all.

Safe by design

  • Keys with the least power

    Each key belongs to one business and does only what the owner ticks: read open times, book, cancel, or approve. Keys can expire, can be revoked, and are stored only as a hash.

  • The salon's rules on every request

    Hours, buffers, notice, daily limits and how far ahead clients can book are checked by the server on every booking, hold and reschedule. No tool accepts a price: prices only come from the owner's settings. The same stylist can never be booked twice for the same time.

  • Safe to retry

    With an idempotency key, a repeated request returns the same booking instead of a second one, and a key can never return another business's booking. Over MCP, a time taken in the meantime comes back with nearby alternatives.

  • A human for the hard parts

    Refunds, complaints and emergencies go to the owner through escalate_to_owner, and intake flags them from the client's own words. Cancelling needs confirmed: true, sent only after the client's yes, and accepting or declining a request needs a key with the bookings:approve scope.

Questions

Which AI assistants can connect?
Any assistant or agent platform that supports remote MCP servers over HTTP, and any code that can call an HTTPS API.
How do I get an API key?
The business owner creates one in Dashboard → Settings → API keys, chooses its scopes and copies it once: it is never shown again.
Can an agent book outside opening hours or change a price?
No. Every booking, hold and reschedule is checked against the owner's hours, buffers, notice and daily limits, and no tool accepts a price: prices only come from the owner's settings.
What if the same request is sent twice?
Send the same idempotency key (idempotencyKey in MCP, the Idempotency-Key header in REST) and the second request returns the first booking.
What happens when a client asks for a refund or complains?
The agent calls escalate_to_owner: the owner is emailed, the hand-off appears in their Inbox and an escalation.created webhook is sent.
Are there rate limits?
Yes. Today each key gets a burst of 120 requests, then 2 per second, counted separately for MCP and REST. Limits may change.

Ready to connect?

Run a salon or studio? Set up your booking link first; your assistant books into it.

Create my free booking link

Building an agent? Write to us and we'll send you the full API and MCP reference.

Email us