Webhook Events
React to booking activity in real time. Astrocal sends signed HTTP POST requests to your endpoint whenever a booking is created, cancelled, or rescheduled.
How Astrocal webhooks work
Point a webhook at any HTTPS endpoint and Astrocal pushes booking events to it as they happen — no polling required.
Webhooks turn Astrocal into an event source for the rest of your stack. Instead of repeatedly calling the API to check whether anything changed, you register an endpoint once and Astrocal delivers a JSON payload the moment a booking event occurs. That makes it straightforward to trigger downstream automation — updating a CRM, posting to Slack, kicking off a fulfilment workflow, or syncing your own database — without writing a single scheduled job.
Each delivery is an HTTP POST with a JSON body, signed with a secret that only
you and Astrocal know. If your endpoint is briefly unavailable, Astrocal retries
automatically with exponential backoff, so a momentary outage never means a lost
event. Webhooks are available on every plan, including Free.
Key parameters
| Name | Type | Default | Description | Required |
|---|---|---|---|---|
| event | string | — | Event type, e.g. booking.created, booking.cancelled, or booking.rescheduled. | — |
| created_at | string | — | ISO 8601 timestamp of when the event occurred. | — |
| data | object | — | The full booking object associated with this event. | — |
{
"event": "booking.created",
"created_at": "2026-03-15T10:00:00Z",
"data": {
"id": "bkg_01abc",
"status": "confirmed",
"start_time": "2026-03-20T14:00:00Z"
}
}Events you can subscribe to
Subscribe an endpoint to one event or all of them — you choose per webhook.
booking.created
A new booking is created. For paid bookings, this fires once payment has been confirmed, so you only ever react to real, paid appointments.
booking.cancelled
An existing booking is cancelled — by the attendee, the host, or via the API. Use it to free up resources or trigger a follow-up.
booking.rescheduled
An existing booking moves to a new time. The payload carries the updated booking so you can keep your own records in sync.
Verify every delivery
Each request carries an X-Astrocal-Signature header so you can confirm it genuinely came from Astrocal.
When you create a webhook, Astrocal returns a signing secret (prefixed
whsec_) exactly once — store it securely. Every delivery includes an
X-Astrocal-Signature header containing an HMAC-SHA256 signature of the raw
request body in the form v1=<hex-digest>, plus an X-Astrocal-Event header
naming the event type. Recompute the HMAC with your secret and compare it using a
constant-time check before trusting the payload. Never act on an unverified
request.
import crypto from "node:crypto";
function verifyWebhookSignature(payload: string, signature: string, secret: string): boolean {
const expected = "v1=" + crypto.createHmac("sha256", secret).update(payload).digest("hex");
if (signature.length !== expected.length) return false;
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}Automatic retries
If your endpoint is down, Astrocal keeps trying — you don't lose events to a blip.
If your endpoint returns a non-2xx status code or doesn't respond within 10
seconds, the delivery is retried with exponential backoff: immediately, then after
1 minute, 5 minutes, 30 minutes, 2 hours, and 24 hours. After six failed attempts
the delivery is marked permanently failed, and you can inspect its full history —
status, response codes, and retry counts — from the dashboard or the API. Because
retries are inevitable in any distributed system, design your handler to be
idempotent: process the same event and booking id more than once without
side effects.
Frequently asked questions
Keep reading
Webhooks guide
Full reference: creating endpoints, payload schemas, headers, and signature verification.
Read moreReferenceBooking API
The REST endpoints that emit these events — create, cancel, and reschedule bookings programmatically.
Read moreIntegrationZapier
Wire booking events into 8,000+ apps with no code using Webhooks by Zapier.
Read more