Quick start
Most teams are receiving events in under five minutes.
- 1
Create an endpoint
In MicroCal, open Developers → Add endpoint. Paste an HTTPS URL from Zapier, Make, n8n, or your own API route. - 2
Copy your signing secret
MicroCal shows the secret once when the endpoint is created. Store it securely — you'll use it to verify incoming requests. - 3
Add optional metadata
Attach static key-value pairs (CRM account IDs, environment tags, routing hints) in the endpoint settings. They are merged into every payload automatically. - 4
Send a test event
Use Send test on the endpoint page. A sample booking.created event should appear in your receiver and in the delivery log. - 5
Verify signatures in production
Reject requests with invalid signatures or timestamps older than five minutes before processing the JSON body.
Event types
Subscribe to one or more events per endpoint.
booking.createdFires when a guest booking is confirmed.
booking.cancelledFires when a booking is cancelled. Includes cancellation metadata.
booking.rescheduledFires when a booking is rescheduled. Includes previous and new times.
Payload shape
All events use version 2026-07-01 and share the same booking object.
booking.created example
{
"id": "evt_abc123",
"type": "booking.created",
"version": "2026-07-01",
"createdAt": "2026-07-06T12:00:00.000Z",
"metadata": {
"crm_pipeline": "sales",
"environment": "production"
},
"data": {
"booking": {
"id": "booking_123",
"status": "CONFIRMED",
"guest": {
"name": "Alex Guest",
"email": "alex@example.com",
"fieldResponses": {
"field_uuid": "Example Co"
},
"customFields": [
{
"id": "field_uuid",
"label": "Company",
"value": "Example Co"
}
]
},
"host": {
"name": "Jordan Host",
"email": "host@example.com"
},
"meeting": {
"title": "Discovery call",
"durationMinutes": 30
},
"bookingPage": {
"slug": "discovery-call",
"title": "Discovery call"
},
"workspace": {
"slug": "acme",
"name": "Acme Studio"
}
}
}
}Custom metadata
Configure static fields on each endpoint in the MicroCal Developers UI.
The top-level metadata object is set per endpoint — not per booking. Use it for values your receiver always needs, like CRM portal IDs, pipeline stages, or environment labels.
Endpoint metadata (configured in MicroCal)
{
"crm_pipeline": "sales",
"environment": "production",
"hubspot_portal_id": "12345678"
}Limits
Guest custom fields
Booking page questions are included automatically on every event.
When you add custom questions to a booking page, MicroCal sends them in two formats:
guest.fieldResponses— raw field ID → value mapguest.customFields— labeled array withid,label, andvaluefor easier CRM mapping
guest.customFields
[
{ "id": "field_abc", "label": "Company", "value": "Example Co" },
{ "id": "field_def", "label": "Phone number", "value": "+61 400 000 000" }
]Request headers
Every delivery is a POST with JSON body and these headers.
| Header | Description |
|---|---|
| X-MicroCal-Event | Event type |
| X-MicroCal-Delivery | Unique delivery ID |
| X-MicroCal-Timestamp | Unix timestamp for signing |
| X-MicroCal-Signature | HMAC-SHA256 of {timestamp}.{rawBody} |
Verify signatures
Always verify before trusting the payload.
Node.js
import crypto from "node:crypto";
export function verifyMicroCalSignature({
secret,
rawBody,
timestampHeader,
signatureHeader,
}) {
const timestamp = Number(timestampHeader);
const now = Math.floor(Date.now() / 1000);
if (!Number.isFinite(timestamp) || Math.abs(now - timestamp) > 300) {
return false;
}
const expected =
"v1=" +
crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
try {
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signatureHeader.trim()),
);
} catch {
return false;
}
}Retries & reliability
MicroCal retries failed deliveries with exponential backoff.
| Retry | Delay |
|---|---|
| 1 | 1 minute |
| 2 | 5 minutes |
| 3 | 15 minutes |
| 4 | 1 hour |
| 5 | 4 hours |
Return any 2xx status quickly after accepting the event. Endpoints with sustained failures are auto-disabled — re-enable them from Developers after fixing the destination.