Use case

Add a booking widget to any website

Embed real-time scheduling on your site with three lines of code. No iframe. Your styles, your fonts, your brand.

<!-- Works on any website -->
<script src="https://cdn.astrocal.dev/widget.js"></script>
<div id="booking"></div>

<script>
  Astrocal.open({
    eventTypeId: 'evt_abc123',
    mode: 'inline',
    target: '#booking'
  })
</script>

How the widget works

Widget loads

The script fetches your event type configuration and available time slots from the Astrocal API. No server-side code required on your end.

Visitor picks a slot

The widget renders a calendar with real-time availability pulled from your connected Google Calendar. Visitors choose a date, time, and fill in their details.

Booking confirmed

The booking is created via the API. Calendar invites go out, confirmation emails send, webhooks fire to your backend, and your onSuccess callback runs.

Set up your booking widget in minutes

1

Install the widget

Add one script tag to your site, or install @astrocal/widget via npm. No build step required for the script tag route.

<script src="https://cdn.astrocal.dev/widget.js"></script>
View docs →
2

Create an event type

Define duration, availability windows, and buffer times. The API returns an event type ID you'll pass to the widget.

curl -X POST https://api.astrocal.dev/v1/event-types \
  -H "Authorization: Bearer ak_live_..." \
  -d '{"name": "30 Min Call", "duration_minutes": 30}'
View docs →
3

Render the widget

Call Astrocal.open() with your event type ID and a target element. The widget handles availability, time zones, and booking creation.

Astrocal.open({
  eventTypeId: 'evt_abc123',
  mode: 'inline',
  target: '#booking'
})
4

Go live

Bookings sync to your calendar, confirmation emails go out, and webhooks fire to your backend. Nothing else to configure.

Why teams choose the Astrocal widget

Not an iframe

The widget renders in a Shadow DOM container on your page. Customize it to match your brand via CSS custom properties.

🎨

Full theme control

Pass a theme object to override primary colour, background, border radius, and font family. Or configure the widget's appearance via the theme object and CSS custom properties.

📅

Real-time availability

Slots reflect your actual Google Calendar. No stale data, no double-bookings. Only genuinely free times are shown.

💳

Payments built in

Stripe is integrated. Clients pay at the point of booking, deposit or full amount. No redirect to a separate checkout page.

🔁

onSuccess callback

When a booking is confirmed, your JavaScript gets called with the full booking object. Redirect, update your UI, or fire analytics.

📦

Three integration paths

Script tag for any website. npm package for bundled apps. React component for component-based UIs. Same API across all three.

API endpoints

GET/v1/availabilityCheck available time slots for an event type over a date range
Response
{
  "slots": [
    {
      "start": "2026-03-28T09:00:00Z",
      "end": "2026-03-28T09:30:00Z"
    },
    {
      "start": "2026-03-28T09:30:00Z",
      "end": "2026-03-28T10:00:00Z"
    },
    {
      "start": "2026-03-28T10:00:00Z",
      "end": "2026-03-28T10:30:00Z"
    }
  ]
}
POST/v1/bookingsCreate a new booking for a selected time slot
Request
{
  "event_type_id": "evt_abc123",
  "start_time": "2026-03-28T09:00:00Z",
  "invitee": {
    "name": "Jane Smith",
    "email": "jane@example.com"
  },
  "metadata": {
    "source": "website-widget"
  }
}
Response
{
  "id": "bk_a1b2c3d4",
  "status": "confirmed",
  "start_time": "2026-03-28T09:00:00Z",
  "end_time": "2026-03-28T09:30:00Z",
  "invitee": {
    "name": "Jane Smith",
    "email": "jane@example.com"
  },
  "cancel_url": "https://api.astrocal.dev/v1/bookings/bk_a1b2c3d4/cancel?token=...",
  "reschedule_url": "https://api.astrocal.dev/v1/bookings/bk_a1b2c3d4/reschedule?token=..."
}

Key parameters

NameTypeDefaultDescriptionRequired
eventTypeIdstringYour event type UUID. Find it in the dashboard or via GET /v1/event-types.
mode'inline' | 'popup'inline renders in-page. popup opens a modal overlay on trigger. Default: inline.
targetstringCSS selector for the container element. Required when mode is inline.
themeobjectOverride design tokens: primary, background, fontFamily, borderRadius.
onSuccessfunctionCallback fired when a booking is confirmed. Receives the full booking object.
localestringBCP 47 locale code for widget copy. Defaults to the browser locale.
metadataobjectKey-value pairs attached to every booking. Useful for attribution and tracking.

Simple, transparent pricing

Start for free. Upgrade as you grow. No hidden fees, no per-seat pricing.

Free

For prototyping

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

Starter

For small teams

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

Pro

Most Popular

For growing teams

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

Business

For scaling up

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

No per-seat pricing. Ever. See full pricing →

Frequently asked questions

Yes. Any platform that lets you add a script tag to the page head or body can run the widget. For WordPress specifically, you can paste the script tag into a Custom HTML block or add it via your theme settings.
Iframes create a sandboxed environment: your CSS can't reach inside, your fonts don't carry over, and cross-origin restrictions complicate communication between the widget and your page. The Astrocal widget renders natively in your DOM, so none of those problems exist.
Yes. Set mode to popup and the widget opens as a modal overlay when triggered. This is useful when you want a 'Book now' button that opens the scheduler without navigating away from the current page.
Pass a theme object with your primary colour, background, border radius, and font family. For more granular control, the widget exposes CSS custom properties you can override directly in your stylesheet.
Yes. Connect your Stripe account in the Astrocal dashboard and set a price on your event type. The widget handles payment collection at the point of booking, with no redirect to a separate checkout page.
The invitee and host both receive confirmation emails with calendar invites. If you passed an onSuccess callback, it fires with the full booking object so you can redirect, update your UI, or fire analytics. Webhooks also fire to your backend if configured.

Add scheduling to your site today

One script tag. Real-time availability. Payments included. Free to start.