Ga naar hoofdinhoud

Booking self-service widget

The booking self-service widget is a white-label, embeddable component that lets any salon or clinic website offer appointment booking without hosting its own Nextcloud instance. It talks to the host Shillinq instance over a public, API-key-authenticated API and renders service selection, slot availability, customer details, and confirmation entirely in the partner's page.

How it works​

Partner website ──(Bearer API key)──▶ Shillinq widget API ──▶ OpenRegister
widget.js /api/widget/{businessId}/… BookingService
BookingResource
Appointment
  • Read endpoints (services, slots) return only safe-public fields — name, duration, optional price, and available times. No customer data is ever returned.
  • Write endpoint (appointments) accepts customer name, email, phone, and notes; these are write-only and never echoed back.
  • Every request must carry Authorization: Bearer {api_key} and is rate-limited to 100 requests/minute per business by default.

1. Issue an API key​

An administrator opens Settings → Widget API keys in Shillinq, enters the business identifier, and clicks Generate key. The plaintext key is shown once and never re-readable — copy it immediately. Keys can be rotated (the previous key keeps working for a 7-day grace window) or revoked instantly.

2. Embed methods​

Iframe​

<iframe src="https://bookings.example.com/booking-iframe.html?businessId=salon-demo"
width="100%" height="800" frameborder="0"></iframe>

Script tag​

<div id="booking-widget"></div>
<script src="https://bookings.example.com/apps/shillinq/widget.js"></script>
<script>
BookingWidget.init({
businessId: 'salon-demo',
apiKey: 'bk_live_...',
apiBase: 'https://bookings.example.com',
containerId: 'booking-widget',
lang: 'nl',
primaryColor: '#21468b',
})
</script>

Web component​

<nextcloud-booking-widget
business-id="salon-demo"
api-key="bk_live_..."
api-base="https://bookings.example.com"
lang="nl">
</nextcloud-booking-widget>
<script src="https://bookings.example.com/apps/shillinq/widget.js"></script>

npm package​

npm install @shillinq/booking-widget
import { SelfServiceWidget } from '@shillinq/booking-widget'

3. Customisation​

Override the --wsw-* CSS custom properties (or pass primaryColor) to match your brand. Dark mode is enabled with --wsw-dark-mode: 1 or the dark config flag.

<style>
.wsw {
--wsw-primary-color: #ff6b6b;
--wsw-font-family: "Playfair Display", serif;
--wsw-border-radius: 8px;
}
</style>

API reference​

MethodPathDescription
GET/index.php/apps/shillinq/api/widget/{businessId}/servicesList public services.
GET/index.php/apps/shillinq/api/widget/{businessId}/slots?serviceSlug=…&date=YYYY-MM-DDAvailable slots (ETag-cached).
POST/index.php/apps/shillinq/api/widget/{businessId}/appointmentsCreate an appointment.

All endpoints require Authorization: Bearer {api_key}. Responses: 401 (invalid/missing key), 429 (Retry-After: 60), 404 (unknown service), 409 (slot just booked), 400 (validation error), 201/200 on success.

Internationalisation​

The widget ships English and Dutch strings and is selected per embed via the lang option. Times are shown in the visitor's browser timezone and stored in UTC.

Security notes​

  • API keys are stored only as password hashes; the plaintext is shown once.
  • Customer PII is write-only and never returned by read endpoints.
  • HTTPS is enforced by the Nextcloud framework; CORS origins are configurable per business (no wildcard).