nisebookings docs

name: nisebookings description: Integrate nisebookings, a hosted booking service (appointments, group sessions, recurring series, packages, waiting lists, event tickets), into a website or app. Use when the user asks to add booking, appointments, reservations, a booking widget, an availability calendar, ticket sales or scheduling to their product. Covers embedding the widget, driving the public REST API from a custom UI, payment flows, and verification.

Integrate nisebookings

Booking is a backend concern. This service owns availability, capacity, pricing, payments and e-mail; the project you are working in owns the UI (or embeds the widget and owns nothing).

Everything is reached at https://app.nisebookings.com with the account's public key. There is no auth on the public side.

0. Check fit first

Refuse or redirect when the user needs: per-night rental pricing (whole-day bookings themselves are supported — durationDays 1–365, one rate per day, the span is fixed once booked), two-way staff calendar sync, SMS, conditional intake questions (plain per-service questions, including file attachments, are supported), a customer-facing UI in a language other than Dutch or English (the widget ships both; mails are Dutch), a customer account with a booking history (cancelling and rescheduling work through magic mail links, not a login), or personal (Calendly-style) scheduling. Those are not supported. If in doubt, read https://guide.nisebookings.com/09-when-to-use.html.

Two APIs, two jobs. The public API (below, no auth) reads the catalogue and creates bookings. The management API (/api/v1, scoped key) configures the account: settings, opening hours, categories, services, staff, per-staff prices, the working week and holidays, plus coupons, extras, notification templates, events, customers, appointments and payments.

For a management-API key, ask the human to create one under Instellingen → API with the scopes you need (catalog:write + settings:write covers a full setup); it is shown once. Call it from a server, never from a browser (no CORS). Conventions: JSON camelCase, PATCH merges, PUT replaces (so PUT /staff/{id}/schedule replaces the whole week), lists paginate with limit/offset and return {data,total}, errors are {"error":{"code","message","fields?"}}.

M=https://app.nisebookings.com/api/v1
H=(-H "Authorization: Bearer nk_…" -H 'Content-Type: application/json')
curl -s "${H[@]}" $M/me                                   # account + the scopes this key has
curl -s "${H[@]}" -X POST $M/services -d '{"title":"Knippen","duration":30,"price":25}'
curl -s "${H[@]}" -X PUT $M/staff/$STAFF/schedule -d '{"days":[{"weekday":1,"start":"09:00","end":"17:00"}]}'

Full walkthrough: https://guide.nisebookings.com/api/

To operate the account through tool calls instead of curl, connect the hosted MCP server with the same key (claude mcp add --transport http nise-booking https://app.nisebookings.com/api/mcp --header "Authorization: Bearer $NISE_API_KEY"); tools mirror /api/v1, including find_slots and a generic api_request. Details: https://guide.nisebookings.com/api/mcp.html

1. Choose the integration path

Situation Path
Standard web app or landing page Widget: <script src="https://app.nisebookings.com/widget.js" defer></script> + <nise-booking data-key="…"> (optional `data-lang="nl
WordPress The nisebookings plugin (listed as nise booking); shortcodes [nise_booking], [nise_events]
Custom UI / mobile / server-side / cart / series / tickets Public REST API (section 3)
Configure the account instead of the human doing it in the admin Management API (section 0 above)

The widget needs no build step and no dependencies, renders in a shadow DOM, and handles the whole flow including the Mollie redirect and return polling. Theme it with --nb-* CSS custom properties on the element. It has no JS API — no methods, no events. If you need programmatic control, use the API.

2. Get the key

Ask the human for the account's public key (admin → Instellingen → Insluiten). The key is not a secret; it belongs in the front-end config. A management key (nk_…) and the Mollie key are secrets: never put them in browser code or commit them.

3. REST API — the flow that always works

Base: https://app.nisebookings.com/api/public/<public key>

# 1. catalogue: account config (timeZone, currency, gateways, depositMode) + services
curl -s "$API/services"

# 2. free slots — send back the exact `start` you get here
curl -s "$API/slots?service=$SVC&staff=any&from=$(date +%F)&days=14&persons=1"

# 3. price (authoritative; recomputed again on booking)
curl -s -X POST "$API/quote" -H 'Content-Type: application/json' \
  -d '{"items":[{"service":"'$SVC'","staff":"'$STAFF'","start":"'$START'","persons":1}],"gateway":"local"}'

# 4. book — 409 slot_unavailable means the slot went to someone else; re-fetch slots and retry.
#    Idempotency-Key: a retry after a timeout with the same key + body returns the same order.
curl -s -X POST "$API/bookings" -H 'Content-Type: application/json' -H "Idempotency-Key: $(uuidgen)" \
  -d '{"items":[{"service":"'$SVC'","staff":"'$STAFF'","start":"'$START'","persons":1}],
       "name":"Ada Jansen","email":"ada@example.com","gateway":"local"}'

Full request/response shapes: https://guide.nisebookings.com/openapi.yaml; recipes (Mollie checkout, recurring series, waiting list, tickets, cart/chain): https://guide.nisebookings.com/04-public-api.html. A runnable end-to-end script: the headless example at https://guide.nisebookings.com/examples/.

Feature map for the item object: extras (id → quantity, clamped server-side), series: "<key>" (+ a series map with the rule) for recurrence, waitlist: true for a full group slot, package: "<token>" to schedule a bought package visit, kind: "package" to buy a package. Multi-item orders = cart/chain; hold: [] on slot searches marks the customer's own picks as taken.

4. Non-negotiables

5. Verify, then report

Verify against a sandbox, not the user's real account. One unauthenticated call creates a 24-hour test account with sample staff and services:

curl -s -X POST https://app.nisebookings.com/api/sandbox
# → {"publicKey","apiKey" (nk_, all scopes, shown once),"expiresAt","endpoints":{…}}

It never delivers mail — GET /api/v1/outbox?to=<email> (or MCP list_outbox) shows what would have been sent, with status suppressed — and its Mollie checkoutUrl is a test page with Betalen / Mislukt buttons that redirects to your returnUrl?nb_pay=<token>. Limits: 5 per hour per IP, 24 h lifetime; DELETE /api/v1/sandbox with its key removes it. Details: https://guide.nisebookings.com/08-sandbox.html

  1. Catalogue and one slot list fetched from the project's real runtime.
  2. One real booking created end to end (a gateway: "local" order needs no payment keys).
  3. Confirm nothing else broke, and tell the user how to see the booking in the admin.
  4. If the booking was only a test, cancel it (admin → Afspraken) or ask the user to.

Do not report an integration as working on the basis of code alone — the verification in steps 1–2 is what makes the claim true.