Embed the calendar on your site
Paste the snippet below and your site shows a real, month-at-a-time calendar for one resource — availability plus a per-night price hint, nothing else. There’s no booking flow here at all: no quote, no hold, no payment. If you want guests to book and pay from your site, see Embed the widget instead — that’s the full booking flow, as a separate, larger script.
Want to see it running before you paste anything? The live calendar demo embeds this exact snippet against a real resource.
The snippet
Section titled “The snippet”<script async src="https://docs.booking-engine.davidvalentino.com/widget/calendar-v1.js"></script><div data-availability-calendar data-key="pk_live_..." data-resource="<RESOURCE_ID>" data-api-base="https://<your-api-host>"></div>Both lines are required. calendar-v1.js is a separate, smaller
script from the booking widget’s v1.js — a site that only wants this
calendar shouldn’t have to load the booking flow’s code too, and vice
versa. It finds every [data-availability-calendar] element on the page
and mounts one calendar into each, inside a Shadow DOM, same isolation the
booking widget uses.
data-key— yourpk_live_…orpk_test_…key. Required. A missing or malformed key replaces the element with a plain “Availability calendar misconfigured — see console” message, visible only in the browser console, never to a guest.data-resource— one resource’s ID. Required. There’s no multi-resource or “all rooms” view — embed one calendar per resource, same limitation as the booking widget’sdata-resource.data-api-base— the API URL the calendar calls, for examplehttps://<your-api-host>. Required in practice: without it the calendar calls the origin of its own script (the docs site, not the API) and every request fails.data-lang—enorid. Optional, defaults toen.data-fallback-contact— optional. Atel:,mailto:, or WhatsApp link shown if the calendar can’t reach the API.
There’s no data-rate-plan-id here — the calendar API has no rate-plan
input at all (priceHintMinorUnits is per-resource, not per-plan). If you
need an exact, bookable price, that’s what POST /v1/quotes and the
booking widget are for.
Mount it from code
Section titled “Mount it from code”The script adds window.BookingCalendar. It works like
window.BookingWidget in Embed the widget:
BookingCalendar.mount(el: HTMLElement, options?: { key, resource, apiBase, lang, accent, radius, font, density, fallbackContact }): { destroy(): void }BookingCalendar.scan(root?: ParentNode): voidmountreturns a handle.handle.destroy()removes the calendar, and you can mount again in the same element.- Mounting an element that already has a calendar does nothing.
- A value passed to
mountwins over thedata-*attribute. - Wait for the script’s
loadevent before you callmount. The React, Next.js, Vue, Nuxt, Svelte, and WordPress examples in Embed the widget work for the calendar too. Use the calendar script URL,window.BookingCalendar, and noratePlanId.
<div id="calendar"></div><script src="https://docs.booking-engine.davidvalentino.com/widget/calendar-v1.js"></script><script> const handle = BookingCalendar.mount(document.getElementById("calendar"), { key: "pk_live_...", resource: "<RESOURCE_ID>", apiBase: "https://<your-api-host>", }); // Later: handle.destroy();</script>What a guest sees
Section titled “What a guest sees”One month at a time, with previous/next navigation. Each available night shows a compact price hint under the day number; unavailable nights show as unavailable, with no further detail. There’s no way to click a date to start a booking — this widget doesn’t carry that flow.
Theme it
Section titled “Theme it”The same five options as the booking widget, all as data-* attributes:
data-accent, data-radius, data-font, data-density, data-lang. See
Embed the widget for the values each one
accepts and what happens if you get one wrong — the behavior is identical
between the two embeds.
Your dashboard’s widget configurator (under Keys) generates both snippets — the booking widget’s and this calendar’s — from the same form, so you don’t hand-type either one.
No PII, ever
Section titled “No PII, ever”Honest failure behavior
Section titled “Honest failure behavior”Same posture as the booking widget: a bad snippet (missing key, missing
resource id) is a mistake in your page, shown only in the console. A
working snippet that can’t reach the API never renders an empty calendar
that could be mistaken for “no availability” — it shows a clear
“Calendar temporarily unavailable” message instead, with your
data-fallback-contact link if you set one.
Next steps
Section titled “Next steps”- Embed the widget — the full booking flow, if you want guests to book and pay from this same calendar.
- Calendar and iCal feeds — the underlying API, if you want to build your own calendar UI instead of using this embed.