Alerts & automation

Microsoft Bookings webhooks

Microsoft Bookings has no webhooks. To get a new appointment into a CRM you would normally poll Microsoft Graph or parse notification emails. BookingsXP sends a signed JSON request to your endpoint the moment a widget booking is confirmed, including the marketing attribution Microsoft never stores.

Plan
Plan: ProNeeds Pro ($19 a month) or Business ($49 a month).
In short
Signed JSON (HMAC-SHA256) to any HTTPS endpoint when a booking is created, with retries and a delivery log.
Microsoft Bookings
Stays your system of record. Bookings land in Outlook and Teams and Microsoft sends the invites and reminders.

How it works

What happens with Webhooks

  • Each delivery is an HTTPS POST with Content-Type application/json and a User-Agent of BookingsXP-Webhooks/1.0.
  • The body is an envelope: id (evt_…), type (booking.created or booking.failed), created, apiVersion (2026-09-01) and data with booking, business, widget and attribution.
  • The BookingsXP-Signature header is t=<unix seconds>,v1=<hex>, where v1 is HMAC-SHA256 of "<t>.<raw body>" keyed with your endpoint's whsec_… secret. BookingsXP-Event and BookingsXP-Delivery headers carry the event type and delivery ID.
  • A 2xx response within 10 seconds counts as delivered. Redirects are not followed. Anything else is retried with exponential backoff, about 30 s, 1, 2, 4, 8, 16, 32 and 64 minutes: 8 retries over roughly two hours.
  • booking.failed is sent when Microsoft rejects a booking for an upstream reason, not when a slot was simply taken or a field was invalid.

Setup

Set up Webhooks

5 steps. Names of menus and buttons are as they appear today; vendors rename things, so look for the closest match.
  1. Step 1: Turn on Store bookings

    Dashboard → widget → Data & access → "Store bookings in BookingsXP". Webhooks carry customer data, so they only fire for widgets that keep a copy.

  2. Step 2: Add a Webhook (JSON) endpoint

    Dashboard → Integrations → Add an endpoint → Webhook (JSON). Enter a name and your HTTPS URL, and choose All widgets or one widget. Copy the signing secret shown after saving: it is displayed once.

  3. Step 3: Verify the signature on your server

    Compute the HMAC over the raw request body, before any JSON parsing, and compare in constant time. Reject timestamps more than five minutes old.

    JavaScript
    // Node.js: verify the BookingsXP-Signature header
    import crypto from "node:crypto";
    
    export function verify(rawBody, header, secret) {
      // header looks like: t=1759312443,v1=5f2c…
      const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
      if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false; // 5-minute replay window
      const mac = crypto.createHmac("sha256", secret).update(t + "." + rawBody).digest("hex");
      return mac.length === v1.length && crypto.timingSafeEqual(Buffer.from(mac), Buffer.from(v1));
    }
  4. Step 4: Handle the payload idempotently

    Retries resend the same envelope with the same id. Store the id (or data.booking.reference) and ignore repeats. Respond 2xx quickly and do slow work in the background.

    booking.created
    {
      "id": "evt_4c1f0d9a7b2e4f6a8c3d5e7f9a1b2c3d",
      "type": "booking.created",
      "created": "2026-10-01T09:14:03.512Z",
      "apiVersion": "2026-09-01",
      "data": {
        "booking": {
          "reference": "BXP-7K2M9Q",
          "id": "AAMkAGI2…",
          "status": "confirmed",
          "start": "2026-10-02T08:30:00.000Z",
          "end": "2026-10-02T09:15:00.000Z",
          "timeZone": "Europe/London",
          "service": { "id": "a1b2…", "name": "Initial consultation" },
          "staff": [{ "id": "c3d4…", "name": "Front desk" }],
          "customer": {
            "name": "Sam Example",
            "email": "sam@example.com",
            "phone": null,
            "notes": null
          },
          "answers": [
            { "questionId": "q1…", "question": "Company size", "answer": "11-50" }
          ],
          "manageUrl": "https://outlook.office.com/book/…",
          "joinUrl": null
        },
        "business": { "id": "b5e6…", "name": "Example Consulting" },
        "widget": { "id": "w_8fk2m1qz", "name": "Homepage" },
        "attribution": {
          "source": "google",
          "medium": "cpc",
          "campaign": "autumn-audit",
          "channel": "Paid search",
          "landingPage": "/audit?utm_source=google&utm_medium=cpc&utm_campaign=autumn-audit",
          "referrer": "https://www.google.com/",
          "pageUrl": "https://www.example.com/book",
          "utm": { "source": "google", "medium": "cpc", "campaign": "autumn-audit" },
          "clickIds": { "gclid": "Cj0KCQjw…" },
          "gaClientId": "1234567890.1759312443"
        }
      }
    }
  5. Step 5: Test, then watch the delivery log

    The Test button sends a ping event ({ "message": "Test notification from BookingsXP" }) so you can check connectivity and signatures. Recent deliveries show status, HTTP code and attempts, with Retry for failures.

Outcomes and caveats

What you get

The result

  • A push the moment a booking is confirmed, instead of polling Microsoft Graph.
  • Customer, answers to your Bookings questions, service, staff, time and time zone in one payload.
  • Source, medium, campaign, channel, UTM values, click IDs (gclid, fbclid, msclkid, li_fat_id and more) and the GA client ID.
  • Signed requests, automatic retries for about two hours, and a delivery log with manual redelivery.

Good to know

Limits and caveats

  • Pro: 5 endpoints across webhooks, Slack and Teams. Business: 25, plus the REST API for reading bookings and analytics.
  • Requires "Store bookings" on the widget.
  • Only bookings made through a BookingsXP widget produce events. Bookings made elsewhere in Microsoft Bookings, and later cancellations or reschedules, do not.
  • Endpoints must be public HTTPS or HTTP URLs; private and local network addresses are refused.
  • Endpoints added from the dashboard subscribe to booking.created.

FAQ

Webhooks questions

Something not covered? Email hello@bookingsxp.com.

Start free, no card

Start on Free with the widget and GA4 events, then move to Pro when you want ad conversions, webhooks and chat alerts.