Add booking to your website in one script tag
Embed real-time scheduling with a script tag. It renders in your page, not an iframe, themed to your colors and fonts. Works on WordPress, Webflow, or any site.
<!-- 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 calendars (Google, Outlook, or CalDAV). 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 onBookingCreated callback runs.
Set up your booking widget in minutes
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>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 ac_live_..." \
-d '{"name": "30 Min Call", "duration_minutes": 30}'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'
})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
Override primary colour, background, border radius, and font family via a theme object, or set the same CSS custom properties directly in your stylesheet.
Real-time availability
Slots reflect your connected calendars (Google, Outlook, or CalDAV). 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.
onBookingCreated 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
/v1/availabilityCheck available time slots for an event type over a date range{
"event_type_id": "evt_abc123",
"timezone": "UTC",
"slots": [
{
"start_time": "2026-03-28T09:00:00Z",
"end_time": "2026-03-28T09:30:00Z"
},
{
"start_time": "2026-03-28T09:30:00Z",
"end_time": "2026-03-28T10:00:00Z"
},
{
"start_time": "2026-03-28T10:00:00Z",
"end_time": "2026-03-28T10:30:00Z"
}
]
}/v1/bookingsCreate a new booking for a selected time slot{
"event_type_id": "evt_abc123",
"start_time": "2026-03-28T09:00:00Z",
"invitee_name": "Jane Smith",
"invitee_email": "jane@example.com",
"invitee_timezone": "America/New_York",
"metadata": {
"source": "website-widget"
}
}{
"id": "bk_a1b2c3d4",
"status": "confirmed",
"start_time": "2026-03-28T09:00:00Z",
"end_time": "2026-03-28T09:30:00Z",
"invitee_name": "Jane Smith",
"invitee_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
| Name | Type | Default | Description | Required |
|---|---|---|---|---|
| eventTypeId | string | — | Your 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. | — |
| target | string | — | CSS selector for the container element. Required when mode is inline. | — |
| theme | object | — | Override design tokens: primary, background, fontFamily, borderRadius. | — |
| onBookingCreated | function | — | Callback fired when a booking is confirmed. Receives the full booking object. | — |
| timezone | string | — | 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
- 10 bookings/month
- 1 calendar connection
- 30 req/min API rate
- Calendar sync
- Email notifications
Launch
For going live
- 50 bookings/month
- 3 calendar connections
- 60 req/min API rate
- Everything in Free
- Custom branding
Grow
Most PopularFor growing products
- 500 bookings/month
- 20 calendar connections
- 500 req/min API rate
- Everything in Launch
- Priority support
Scale
For high volume
- 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
Keep reading
Google Calendar sync
Connect your calendar so the widget always shows real-time availability.
Read moreUse CaseAppointment reminders
Reduce no-shows with automated email reminders before each booking.
Read moreCore ProductAll features
See everything Astrocal offers, from availability rules to webhooks and payments.
Read moreAdd scheduling to your site today
One script tag. Real-time availability. Payments included. Free to start.