nisebookings
A hosted booking service for businesses: appointments, group bookings, recurring series, packages, waiting lists and event tickets. It ships three surfaces:
| Surface | What it is | For |
|---|---|---|
| Embeddable widget | two dependency-free web components you paste into any site | any website, WordPress |
| Public REST API | the same engine without UI, one public key per business | custom front-ends, apps, agents |
| Admin back office | calendar, appointments, catalogue, payments, mail templates | the business |
The engine is strict where it matters: slots are re-checked and written transactionally, capacity can never be exceeded, prices are always recomputed server-side, and all time is anchored to the business's time zone.
Start here
| Your task | Read |
|---|---|
| Decide whether this fits (and when not to use it) | When to use it |
| Test against a throwaway sandbox, no sign-up | Sandbox |
| Put bookings on a website in 5 minutes | Quickstart |
| Understand services, slots, capacity, money, time | Concepts |
| Configure the widget (attributes, flows, styling) | Widget reference |
| Build a custom front-end on the API | Public API · openapi.yaml · verified examples |
| Integrate into a Next.js app | Next.js · runnable example |
| Configure your account from code (no admin UI) | Management API · openapi.yaml |
| Let Claude Code, Codex, Cursor or VS Code operate your account | MCP server |
| Get notified of bookings, cancellations, tickets and payments | Webhooks |
| Use the back office | Admin guide |
| Change e-mail templates | Notifications |
| Know what data is stored and who can see it | Data and privacy |
| Feed a coding agent | Agent instruction files |
5-minute integration
<script src="https://app.nisebookings.com/widget.js" defer></script>
<nise-booking data-key="<your public key>"></nise-booking>
The customer gets service → time → details → payment → confirmation, in a shadow-DOM element that
inherits your page's font and is themed with CSS custom properties. Event tickets:
<nise-events data-key="…">. WordPress: paste the same two lines into a Custom HTML block.
Headless integration
const API = 'https://app.nisebookings.com/api/public/<your public key>';
const { tenant, services } = await (await fetch(`${API}/services`)).json();
const { days } = await (await fetch(`${API}/slots?service=${id}&from=2026-10-14&days=7`)).json();
const res = await fetch(`${API}/bookings`, {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
items: [{ service: id, staff: days[0].slots[0].staffId, start: days[0].slots[0].start, persons: 1 }],
name: 'Ada Jansen', email: 'ada@example.com', gateway: 'local',
}),
});
Send back the exact start you were given; handle 409 slot_unavailable by re-fetching slots. Add an
Idempotency-Key header so a retry after a timeout never books twice.
The five things to know
- Account = public key. One key identifies the business on every public call. Nothing else is needed to embed or book.
- One order = one payment. A cart, a chain, a repeated series or the parts of a compound service are all one checkout, with one payment and one order token.
- The client never decides. Prices, staff, extras, capacity and slot availability are recomputed
server-side inside a transaction with per-staff locks. The only thing the client must get right is
sending back the
start(andstaffId) it received. - Time is UTC on the wire, business-local in the UI. Slot
startvalues are ISO UTC;from/untilare business-local dates; schedules, holidays and reminders use the business time zone. - Timed work runs on its own. Reminders, mail delivery, payment expiry, waiting-list offers and automatic status changes are processed by the service about once a minute; there is nothing to schedule on your side.
For AI agents and coding agents
agents/— drop-in instruction files:AGENTS.md(Codex, Cursor, Copilot coding agent, VS Code, …), a Claude Code skill, and a Copilot instructions file. Copy one into the project that integrates this service.08-sandbox.md—POST /api/sandboxreturns a 24-hour test account with a public key and an all-scopes API key; no mail is delivered (read it viaGET /api/v1/outbox), payments are fake. Verify your integration there before touching your real account.10-webhooks.md— signed event messages (Standard Webhooks) to your backend for bookings, tickets and payments, with retries and a deliveries log; a dependency-free verifier.examples/— three smallest-possible integrations; all run against a sandbox key, including a full Next.js app (widget and own UI) with every page explained in11-nextjs.md.llms.txt— this documentation as an index, per the llmstxt.org convention.llms-full.txt— every guide page concatenated into one file.openapi.yaml·openapi.json— machine-readable description of the whole public API (OpenAPI 3.1), in YAML and JSON.
When implementing a booking feature: start at Quickstart, fall back to the Public API for anything the widget does not expose, and treat Concepts as the source of truth for slot, capacity and pricing semantics. The Data and privacy page explains what is stored, how accounts are isolated and what is reachable from outside.
What this service is not (yet)
- The management API and the MCP server cover what the admin does except creating real accounts (a 24-hour sandbox can be created with one call) and the dashboard statistics. The MCP server takes API keys only (no OAuth yet).
- No customer accounts or "my bookings" area; bookings are managed through magic links: cancel a
single booking (
/b/<token>) or a whole order (/o/<token>), reschedule a single booking on/b/<token>or withPOST bookings/{token}/reschedule. - No SMS/WhatsApp and no external calendar sync.
- Admin UI is Dutch-only; the widget's text is Dutch and English (
data-lang, or the account's language in Instellingen → Algemeen). - No plans, quotas or billing layer — accounts are isolation + roles.
09-when-to-use.md turns this into a decision table with alternatives.