Astrocal
Booking Widget

The booking widget that disappears into your brand

Drop it in with one line of code. Theme every pixel, check real-time availability, take Stripe payments. Renders in your DOM, not an iframe.

See it live. Ship it today.

See it live. This is a real booking widget.

Blue
Violet
Emerald
Rose
--astrocal-primary: #2563eb

Add the script tag

One line of HTML, or an npm install. The widget renders natively in your DOM, not an iframe. Shadow DOM isolation keeps your CSS and the widget from ever colliding.

Theme it to your brand

Pass a theme object or override CSS custom properties. Primary colour, background, border radius, font family: all yours. Paid plans remove every trace of Astrocal branding.

Handle the booking your way

onBookingCreated fires with the full booking object the moment someone books. Redirect to a thank-you page, update your UI, or fire analytics. Your call.

<!-- Add to any page -->
<script src="https://cdn.astrocal.dev/widget.js"></script>
<div id="booking"></div>

<script>
  Astrocal.open({
    eventTypeId: 'evt_abc123',
    mode: 'inline',
    target: '#booking',
    theme: { primaryColor: '#6366f1' },
    onBookingCreated: (booking) => {
      window.location.href = `/thank-you?id=${booking.id}`
    }
  })
</script>

Built for embedding

โšก

DOM-native, not an iframe

The widget renders straight into your page inside a Shadow DOM container. No cross-origin quirks, no scrollbar bugs, no CSS conflicts.

๐ŸŽจ

Theme every pixel

Override primary colour, background, border radius, and font family with a theme object or your own stylesheet. Full design control, no forking.

๐Ÿ“…

Real-time availability

Slots reflect your connected calendars: Google, Outlook, or CalDAV. Free/busy checks run on every request, so only genuinely open times show. No stale slots.

๐Ÿ’ณ

Stripe payments at booking

Collect a deposit or full payment inline. Stripe Connect handles 135+ currencies. No redirect to a separate checkout page.

๐Ÿ”

Booking callbacks

onBookingCreated fires with the full booking object. onPaymentRequired, onError, and onClose cover the rest. Redirect, update state, fire analytics, or trigger a workflow.

๐Ÿ“ฆ

Popup or inline

Mount inline on a dedicated booking page, or open as a modal overlay from any button. Popups close on backdrop click or Escape.

Key parameters

NameTypeDefaultDescriptionRequired
eventTypeIdstringโ€”Your event type UUID. Find it in the dashboard or via GET /v1/event-types.
mode'inline' | 'popup'โ€”inline renders in-page inside a target element. popup opens a centered modal overlay. Default: inline.โ€”
targetstringโ€”CSS selector for the container element. Required when mode is inline.โ€”
themeobjectโ€”Override design tokens: primaryColor, backgroundColor, fontFamily, borderRadius, and more. Applied via CSS custom properties.โ€”
onBookingCreatedfunctionโ€”Callback fired when a booking is confirmed. Receives the full booking object. onPaymentRequired, onError, and onClose are also available.โ€”
timezonestringโ€”IANA timezone override for displayed slots. Auto-detected from the visitor's browser if not provided.โ€”
colorScheme'light' | 'dark' | 'auto'โ€”Light, dark, or auto. Auto detects the visitor's system preference. Defaults to auto.โ€”

Pricing that scales with bookings, not seats

Start free with 10 bookings a month, no credit card. Paid plans from $12, and team members never cost extra.

Free

For prototyping

$0forever
  • 10 bookings/month
  • 1 calendar connection
  • 30 req/min API rate
  • Calendar sync
  • Email notifications

Launch

For going live

$12/month
  • 50 bookings/month
  • 3 calendar connections
  • 60 req/min API rate
  • Everything in Free
  • Custom branding

Grow

Most Popular

For growing products

$49/month
  • 500 bookings/month
  • 20 calendar connections
  • 500 req/min API rate
  • Everything in Launch
  • Priority support

Scale

For high volume

$199/month
  • 5,000 bookings/month
  • 100 calendar connections
  • 2,000 req/min API rate
  • Everything in Grow
  • Dedicated support

No per-seat pricing. Ever. See full pricing โ†’

Frequently asked questions

Pass a theme object with primary, background, fontFamily, and borderRadius. For more granular control, the widget exposes CSS custom properties you can override directly in your stylesheet. On paid plans, the 'Powered by Astrocal' attribution is removed.
The widget script is under 30 KB gzipped. It loads asynchronously and never blocks your page render. No runtime dependencies.
All modern browsers: Chrome, Firefox, Safari, and Edge (latest two major versions). The widget uses standard DOM APIs with no polyfills required.
Yes. The npm package works with any bundler. A dedicated React component is available via @astrocal/react. For Vue, Svelte, or others, use the vanilla open() function. It works anywhere you can run JavaScript. Prefer no JavaScript at all? Drop in a <div data-astrocal-event-type-id="..."> and the widget initializes itself.
Inline mode renders the widget inside a target element on your page, ideal for dedicated booking pages. Popup mode opens the widget as a centered modal overlay, triggered by a button click, better for 'Book now' CTAs that shouldn't navigate away.
Yes. Connect your Stripe account and set a price on your event type. The widget handles payment collection at the point of booking (deposit or full amount) with no redirect to a separate checkout page.

Embed scheduling in minutes

One script tag. Your brand. Real-time availability. Payments built in. Free to start.