Integrate Cadence
Cadence is a multi-tenant appointment engine. Add real booking to your product in two ways: drop in our prebuilt UI, or build your own against the REST API. Everything below is public — no login required to read.
Two ways to integrate
Whatever you ship, your customers' bookings land in the same dashboard and fire the same webhooks. Pick a path — or mix them per surface.
Use our prebuilt UI
A fully-branded booking flow with zero UI work: link to a hosted page, paste a script tag for the widget, or render native React components. No API key in the browser.
Build your own
Call the REST API from your backend with an org key, or the keyless public surface from the browser. Wire your own UI, automate with the MCP server, react to webhooks.
What's available
Full REST API
Services, availability, bookings, webhooks. Server-side with ck_… keys, plus a keyless public surface for browsers.
MCP server for AI agents
12 tools that let an AI agent set up an org and manage bookings in natural language. Works with Claude and any MCP client.
Set up the MCP server →Prebuilt UIHosted pages, widget & React
A hosted booking page, a drop-in widget.js (inline or modal), and native @cadence/react components.
Interactive API reference
Every endpoint and response shape, generated from the live OpenAPI schema. Try requests right in the browser.
Open/api/docs ↗Core concepts
Four objects, scoped per organization (your tenant):
- Organization — the tenant. Every object belongs to one org; a key only ever sees its own org's data. Identified publicly by a
slug(e.g.movela). - Service — what's booked: a name, duration, location type (
in_home/virtual/in_person), and an optional price. - Practitioner — who delivers a service. Has weekly hours, buffers, minimum notice, and a booking horizon that together generate availability.
- Booking — a confirmed slot for a customer. Times are UTC instants; render them in the customer's timezone.
One deployment serves every org by slug, and bookings never double-book — the guarantee is enforced in Postgres, so two racing requests can never both win.