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

    Create an endpoint

    In MicroCal, open Developers Add endpoint. Paste an HTTPS URL from Zapier, Make, n8n, or your own API route.
  2. 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. 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. 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. 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.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",
        "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

Up to 20 fields per endpoint. Keys must start with a letter and use letters, numbers, and underscores. Values are strings (max 500 characters).

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

200 OK but nothing happens on my side

A 2xx response only means MicroCal reached your URL successfully. If the response body is HTML, you are likely hitting a web page instead of a webhook handler. Confirm the URL accepts POST requests and logs the JSON body.

Configure in MicroCal

Team & Business plans

Workspace owners manage endpoints from the Developers section — add URLs, metadata, inspect delivery logs, and rotate secrets.
Sign in to configure webhooks