Skip to content

Booking on your own website

Put Booking Orbit on your website with the widget, or build your own booking screens with the JavaScript SDK and the public booking API.

Tutorial3 min read

There are three ways to take bookings on your own website, from least to most work:

  1. A link to the hosted booking page.
  2. The widget, which shows the booking page inside your page or in a popup.
  3. The SDK or the public booking API, to build screens in your own design.

The widget

Add the script once, then a placeholder where the booking page should appear:

HTML
<script src="https://app.bifrostorbit.com/booking/widget.js" async></script><div data-booking-orbit="northwilds-oslo" data-service="boot-fitting"></div>

Or open it in a popup from any button or link:

HTML
<button type="button" data-booking-orbit-open="northwilds-oslo" data-service="boot-fitting">Book a fitting</button>

Optional attributes: data-service (start with one service), data-staff (a person's id), data-lang (en, nb, de). The frame grows with its content, so there is no inner scroll bar. From your own code, window.BookingOrbit.open({ location: 'northwilds-oslo', service: 'boot-fitting' }) opens the popup.

Booking page in Booking Orbit has the code ready to copy.

The SDK

Shell
npm install @bifrost-orbit-booking/sdk
TypeScript
import { createBookingClient } from "@bifrost-orbit-booking/sdk";const booking = createBookingClient({ baseUrl: "https://app.bifrostorbit.com/booking", location: "northwilds-oslo", locale: "en" });const services = await booking.services();const slots = await booking.slots({ service: services[0]!.id, timeZone: "Europe/Oslo", days: 7 });const time = slots.days.flatMap((day) => day.slots)[0]!;const hold = await booking.hold({ service: services[0]!.id, startsAt: time.startsAt });const { appointment } = await booking.book({ service: services[0]!.id, startsAt: time.startsAt, holdToken: hold.token, name: "Ingrid Berg", email: "ingrid@northwilds.com" });

The client has location(), services(), service(), staff(), slots(), nextAvailable(), hold(), release(), book(), appointment(), reschedule(), cancel(), calendarUrl() and joinWaitlist(). A taken time throws BookingConflictError; isTimeTaken(error) checks for it.

To book from the browser on your own website, add the website under Settings, allowed websites. Reading services and free times works from any website. A website space connected in CMS Orbit adds its own addresses.

To move an appointment, pass its manage token to slots({ service, manage }), so the appointment's own time counts as free, then call reschedule().

The public booking API

Everything the SDK does is plain JSON over HTTPS at https://app.bifrostorbit.com/booking/api/public/<location>:

GET
Path
/
What it does
The location: name, address, time zone, languages, opening hours, what the booking page asks
GET
Path
/services
What it does
Listed services
GET
Path
/services/<id or address>
What it does
One service, with its people and form questions
GET
Path
/staff?service=
What it does
People who can be booked
GET
Path
/slots?service=&staff=&from=&days=&timeZone=&manage=
What it does
Free times, grouped by day in the time zone you ask for (up to 42 days), and the next free time
POST
Path
/holds
What it does
Hold a time for 10 minutes: { service, staff, startsAt }
DELETE
Path
/holds/<token>
What it does
Let a held time go
POST
Path
/appointments
What it does
Book: { service, staff, startsAt, holdToken, name, email, phone, notes, answers, marketing, locale, timeZone }
GET
Path
/manage/<token>
What it does
An appointment by its manage token
POST
Path
/manage/<token>/reschedule
What it does
Move it: { startsAt, staff }
POST
Path
/manage/<token>/cancel
What it does
Cancel it: { reason }
GET
Path
/manage/<token>/calendar
What it does
The appointment as a calendar file
POST
Path
/waitlist
What it does
Join the waitlist: { service, staff, from, to, name, email }

Answers come as { "data": … }, errors as { "error": { "code", "message" } }. Times are ISO 8601 in UTC. Holding, booking and changing are limited per visitor, and answer 429 when there are too many tries.

Was this page helpful?

Read next