Hosted booking widget

An availability calendar and a booking-request form for hotels on the 99tales widget API, embeddable on any web page. No backend, no build step, no framework — one script tag and two elements.

What you paste

<availability-checker> is the calendar with a live bookability verdict; <booking-widget> is the request form. Use either or both — on the same page the checker hands its dates to the form automatically. Everything else is configuration, and all of it rides on the script tag.

Before it works on your page: the hotel and the exact origin of the embedding page (e.g. https://www.hotel.com) have to be registered with the service. An unregistered origin is refused — this is what stops anyone else from putting a hotel's booking form on their own site. Ask us to add yours.

Build it

Set the hotel, the look and the behaviour on the left. The snippet on the right is the finished embed — it updates as you go, and it is the whole integration.

<availability-checker>
<booking-widget>

Two independent elements — the dashed outlines are this page's, not theirs. Place them wherever you like, together or pages apart; when they share a page the checker hands its dates to the form. The preview always runs on our test hotel, whatever ID you type on the left — so you can submit it as often as you like without anyone receiving anything.

Theme reference

Each knob is data-<name> on the script tag, or ?<name>= on the script URL. Unset knobs keep the values in the second column. Colours accept hex, rgb(), or a CSS colour name; lengths accept any CSS length (a bare number means pixels).

Behaviour reference

Options that change behaviour rather than looks. Same two channels as the theme knobs — data-<name> on the script tag or ?<name>= on its URL — and each one also works as a plain attribute on the element itself, which is what you want when two instances on one page need to differ. The attribute wins.

Language, bot protection and the API credentials need no configuration: the script arms Turnstile for the hotel by itself, the widget-API secret never leaves the service, and the language is detected from the page.

Two things are deliberately not on this list. turnstile-site-key comes from the hotel's registration, so you cannot get it wrong. room-options / room-groups are JSON built from a property's room data rather than something to hand-write into a script tag — set those on the element if your page can.

Links out of the form

privacy-policy-url and thank-you-page-url take either shape, and the difference matters:

Anything else — www.hotel.com/datenschutz, with no https:// and no leading slash — is refused with a message in the browser console rather than turned into a broken link.

Host pages

Any HTML page

Paste the snippet. That is the whole integration — the script registers the two elements and everything else is theming.

Site builders and tag managers

Some hosts load the script themselves and strip data- attributes on the way. Every option is therefore also accepted as a query parameter on the script URL, which nothing can strip:

In a hex colour, # has to be written %23 in a URL — or just leave it off, primary=6b5244 is read as hex too. Where the host also won't let you set attributes on the elements, the behaviour options above are unavailable; the theme knobs all still work.

One example: on Wix, use Add → Embed Code → Custom Element with Server URL set to the script URL and Tag name to booking-widget; a second Custom Element with the same URL and the tag name availability-checker adds the calendar. Loading the script twice is harmless.

What will not work

An iframe-based embed box — Wix's "Embed HTML", and its equivalents elsewhere — runs the page on the builder's own sandbox domain, not on the hotel's. That is a different origin from the one registered for the hotel, so the requests are refused. Use a real custom-element or raw-HTML block that runs on the site's own domain.