Apointoo

Built for the four hard problems in appointment scheduling.

Multi-tenancy, concurrency, headless delivery, and attribution. Most tools solve one or two. Apointoo is designed around all four.

HeadlessAttributionAdaptersMulti-tenancy
01

Headless delivery

The SDK exposes a single handler. Mount it on your API route and it handles the rest. The UI is yours. No iframes, no vendor pop-ups, no forced redirects. Build the experience your brand requires and let Apointoo handle the booking logic underneath.

// app/api/booking/route.ts
import { app } from '@/lib/booking'
export { app as POST }
02

Attribution

Click IDs (GCLID, fbclid, msclkid) and UTM parameters are captured when the booking form loads, not on page load. When the appointment is confirmed, the full attribution payload travels with it. Offline conversions are uploaded to Google Ads and Meta via the respective APIs.

// Attribution captured at submission time
const attribution = getAttribution()
// { gclid: 'xxx', utm_source: 'google', ... }
03

Adapter model

Every integration point (booking backend, notification channel, state store, dedup layer) is an adapter. Swap BLVD for OpenDental without touching your frontend. Add Twilio alongside Brevo. The core handler interface stays constant.

createBookingHandler({
  booking: blvdAdapter({ apiKey: env.BLVD_KEY }),
  notification: brevoRestAdapter({ apiKey: env.BREVO_KEY }),
  persistence: sheetsAdapter({ spreadsheetId: env.SHEET_ID }),
  dedup: upstashAdapter({ url: env.UPSTASH_URL }),
})
04

Multi-tenancy

Pass a tenant resolver and Apointoo routes each booking request to the correct backend configuration. Clinic chains and agency builders can serve dozens of clients from a single handler deployment.

createBookingHandler({
  tenant: (req) => req.headers.get('x-tenant-id') ?? 'default',
  tenants: {
    'clinic-a': { booking: blvdAdapter({ apiKey: env.BLVD_A }) },
    'clinic-b': { booking: openDentalAdapter({ url: env.OD_B_URL }) },
  },
})

Adapter compatibility

Every integration in the SDK follows the same adapter interface. Switch backends without touching application code.

AdapterTypeStatus
BLVDbookingproduction
OpenDentalbookingbeta
direct-confirmbookingproduction
Brevo RESTnotificationproduction
Twilio WhatsAppnotificationbeta
Sheetspersistenceproduction
Upstashdedupproduction

Pipeline overview

Every booking passes through the same deterministic pipeline. Each stage is handled by the appropriate adapter.

Submission received
Dedup check (Upstash)
Vendor session opened
Confirm or cancel
Notification dispatched
State persisted

Reserve with Google, built in.

The SDK ships with a feed publisher for Google's Reserve with Google program. Configure your availability feed and your clients' services appear on Google Search and Maps, bookable directly from the results page.