Bookitive
Developers

Embed the widget

Embed the Bookitive seat map and checkout on your own site — the loader, every mount option, the events it emits, the controller API, and the captcha-safe checkout.

Not verified yet

The widget is Bookitive's seat-map UI — seat picking, live availability, and checkout — as a drop-in you host on your own page. Buyers never leave your domain, while payments, captcha, and phone verification run safely on Bookitive's side.

The quick embed

The copy-paste snippet from Share & embed:

<div id="bookitive-tickets"></div>
<script src="https://events.bookitive.com/widget/v1.js"></script>
<script>
  Bookitive.mount(document.getElementById('bookitive-tickets'), {
    baseUrl: 'https://api.bookitive.com',
    org: 'your-org',
    event: 'your-event',
  });
</script>

For a real app, use @bookitive/widget-js — the @stripe/stripe-js pattern: don't bundle the runtime, inject it and get a typed mount().

import { loadBookitive, type BookitiveCustomEvent } from '@bookitive/widget-js';

const bk = await loadBookitive(); // injects events.bookitive.com/widget/v1.js
const el = document.getElementById('seatmap')!;

const controller = bk.mount(el, {
  org: 'city-theatre',
  event: 'spring-gala-2027',
  legend: true,
});

el.addEventListener('bookitive:selectionchanged', (e) => {
  const { selection, totalCents } = (
    e as BookitiveCustomEvent<'bookitive:selectionchanged'>
  ).detail;
  // update your cart…
});

loadBookitive() is idempotent (repeated calls reuse the in-flight promise or the already-loaded global) and rejects during SSR — call it from onMount / useEffect.

Mount options

Prop

Type

Events

The host page owns tabs, cart, and the checkout button; the widget reports everything through bubbling CustomEvents on the mount element, each typed via BookitiveCustomEvent<'…'>:

  • bookitive:ready — { event }, the full public event payload (floors, ticket types, protection flags).
  • bookitive:selectionchanged — { selection, totalCents }, your cart hook.
  • bookitive:seatselected / bookitive:seatdeselected — { seatId, code? } (deselect can carry reason: 'taken' when live availability revokes a seat).
  • bookitive:limitreached — { ticketTypeId, ticketTypeName?, max }, so you can show "max N per order".
  • bookitive:error — { message }.

The controller

mount() returns a controller to drive the widget:

  • setFloor(floorId), getSelection(), clearSelection(),
  • selectAvailableByType(ticketTypeId) — bulk-select all free seats of a type,
  • mountCaptcha(el), verifyStart(phone), verifyCheck(phone, code),
  • checkout(input) → the created order,
  • destroy().

Captcha-safe checkout

controller.checkout() routes the order submission through a mounted captcha bridge on Bookitive's origin — so Turnstile and phone verification are solved and verified on Bookitive's side, and your host domain never configures captcha at all. This is what lets you wrap a completely custom checkout UI around the widget without taking on bot-protection yourself.

The published type definitions can trail the live runtime by a release. If an option or method here isn't in your installed .d.ts yet, it's a type lag, not a missing feature — upgrade @bookitive/widget-js, or consult the interactive reference at api.bookitive.com/public/v1/docs.

On this page