Skip to main content
This changelog covers the BoothZen public API (/api/v1/*), webhooks, and the developer-facing surface area (SDKs, plugins, portal). It follows Keep a Changelog conventions.
Future API changes will be additive within v1 — new fields, new endpoints, new optional parameters. Breaking changes will ship as v2 with parallel availability for at least 12 months.

API additions — 2026-05-26

Additive extensions to v1 driven by the candidcamera-integration workstream. All backwards-compatible; existing keys keep working without changes.

Added

  • POST /api/v1/payment-intents — create a Stripe payment intent for an existing booking and capture the card inline using Stripe Elements (no redirect, no iframe). Requires the new payments:write scope. Returns { id, client_secret, status, amount, currency, booking_id, created_at }.
  • GET /api/v1/payment-intents/{pi_id} — retrieve a payment intent by its Stripe id for server-side reconciliation. Requires the new payments:read scope. Tenant isolation: a foreign intent returns 404 to avoid revealing its existence.
  • Two new scopes on ApiKey: payments:read, payments:write. ScopeCatalog grows from 16 → 18 ids.
  • price_from on GET /api/v1/availability — each day in the response now carries price_from: { amount, currency } | null (the cheapest visible package on that date, with holiday-rule adjustment applied) so partners can render a “from £X” calendar label without a second round-trip.
  • metadata bag on Booking / Customer / Lead / Invoice — opaque key/value passthrough, up to 50 keys, max 500-char string values. Use for partner-side correlation IDs (venue lookups, lead UUIDs, UTM tags, GA4 client ids, accounting-system references). Round-trips through POST/PATCH/GET verbatim. Wholesale-replace on PATCH (no key-level merge).
  • POST /api/v1/bookings now computes total_amount when package_id is provided — base price × holiday-rule adjustment for the event_date, with deposit_amount mirroring the package’s flat or percentage deposit on the adjusted total. Lets partner wizards display a real price at “review” step without a separate quote endpoint or a follow-up PATCH. Without package_id, total stays 0 (backwards-compat with the pre-v0.5 PATCH-later flow).

Laravel SDK releases

  • boothzen/laravel-sdk v0.2.0BoothZen\Laravel\Webhooks\Events typed constants for the 13 outbound events; paymentIntents()->create() resource.
  • v0.3.0me()->get() for API-key introspection (tenant + scopes + mode); leads()->createWithCustomer() two-step helper for anonymous lead capture; paymentIntents()->get() for retrieve-by-id.
  • v0.4.0availability()->list($from, $to) returning list<AvailabilityDay> with per-unit slots and the new price_from Money.
  • v0.5.0metadata: array<string,string> on Booking/Customer/Lead/Invoice DTOs; Booking::fromArray() reads the canonical total_amount envelope field (was previously expecting total, which never existed on the wire).

v1.0.0 — 2026-05-10

The v1 contract lock. Everything below was shipped across Phases 140 through 148 and is covered by Spectator contract tests in CI.

Added

  • Public REST API v1 (Phase 140). 7 resource controllers (bookings, leads, quotes, invoices, customers, services, units) and the availability endpoint. Cursor pagination, prefixed string IDs (bk_, ld_, qt_, inv_, cu_, srv_, un_), {amount, currency} money envelopes, ISO-8601 UTC datetimes. Stripe-shape error envelopes. IETF RateLimit-* headers and per-API-key buckets (600/min).
  • API key surface (Phase 140-01). bz_live_* and bz_test_* Bearer keys with SHA-256-hashed storage, scope enforcement, and full mode isolation. Managed at admin/settings/api-keys.
  • Idempotency (Phase 140-04). Idempotency-Key header on POST/PATCH with 24h Redis-backed replay cache, keyed per tenant + key.
  • OAuth 2.1 PKCE (Phase 141). /oauth/authorize + /oauth/token endpoints, mandatory PKCE, rotating refresh tokens, tokens interchangeable with API keys on /api/v1/*. Apps managed at admin/settings/oauth-apps.
  • Webhooks (Phase 142). 13 fan-out events from 6 observers, Stripe-pattern HMAC-SHA256 signatures (BoothZen-Signature: t=...,v1=...), 5-minute tolerance window, 1m–12h exponential-backoff retries, auto-disable after 20 consecutive failures.
  • Widget SDK polish + full-flow booking widget (Phase 143).
  • Laravel SDK (Phase 144). Published to Packagist as boothzen/laravel-sdk, built on Saloon v4. Includes SignatureVerifier helper for webhooks.
  • WordPress plugin v0.1.0 (Phase 145). Custom post type bz_booking, 4 Gutenberg blocks, 4 shortcodes, Elementor + Divi bridges, webhook receiver, WP-CLI commands.
  • Joomla 5 module v0.1.0 (Phase 146).
  • Zapier + Make.com integrations (Phase 147).
  • Developer portal at developer.boothzen.com (Phase 148). Live OpenAPI 3.1 spec, no spec drift, single source of truth for credentials management deep-linked to the main app.

Conventions locked in v1

  • Money is always { amount: <integer minor units>, currency: <ISO-4217> }.
  • Datetimes are always ISO-8601 UTC with the Z suffix.
  • Resource IDs are always opaque strings with a stable prefix.
  • Pagination is always cursor-based (?cursor=...&limit=25, next_cursor in body).
  • Errors are always the Stripe-shape envelope (error.type, error.code, error.message, error.request_id).
  • Two equivalent hosts: https://app.boothzen.com/api/v1/* (canonical) and https://{slug}.boothzen.com/api/v1/* (tenant-branded).