Developer docs

Webhooks

Receive signed booking events at your HTTPS endpoint. Connect Zapier, Make, HubSpot workflows, or your own API without building a custom MicroCal integration.

Quick start

Most teams are receiving events in under five minutes.

  1. 01

    Create an endpoint

    In MicroCal, open Developers Add endpoint. Paste an HTTPS URL from Zapier, Make, n8n, or your own API route.
  2. 02

    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. 03

    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. 04

    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. 05

    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.created
Fires when a guest booking is confirmed.
booking.cancelled
Fires when a booking is cancelled. Includes cancellation metadata.
booking.rescheduled
Fires 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",
        "phone": "+61400000000",
        "fieldResponses": {
          "field_uuid": "Example Co"
        },
        "customFields": [
          {
            "id": "field_uuid",
            "label": "Company",
            "value": "Example Co"
          }
        ]
      },
      "host": {
        "id": "user_123",
        "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"
}

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 map
  • guest.customFields — labeled array with id, label, and value for 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.

HeaderDescription
X-MicroCal-EventEvent type
X-MicroCal-DeliveryUnique delivery ID
X-MicroCal-TimestampUnix timestamp for signing
X-MicroCal-SignatureHMAC-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.

RetryDelay
11 minute
25 minutes
315 minutes
41 hour
54 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.

Troubleshooting

Configure in MicroCal

Sign in to configure webhooks