|

Scheduling integrations and boundaries

Calendar, conferencing, payment, email, SMS, webhook, embed, machine access, MCP, AI chat, and storage integrations in current source.

A connection or provider record describes a configured integration. It is not proof that credentials work, that a provider accepted a request, or that money moved. Each integration below fails at the point of use when it is not configured. Booking flows that do not depend on it keep working.

How delivery works

Integration side effects are written as outbox rows (CalendarOperation, ConferenceOperation, PaymentOperation, WebhookDelivery, ReminderDelivery, WorkflowActionExecution, TeamInvitationDelivery) and processed by processSchedulingOutbox. Rows move through pending, processing, succeeded, retrying, and dead_letter. Operators retry dead-lettered rows from the integrations, payments, webhooks, and workflows pages with the matching retry* command. Outbound HTTP to webhooks, SMS, and reminders goes through safeEgress.ts, which blocks private, loopback, link-local, and other non-public address ranges.

Calendars

Adapters: features/integrations/calendar/google.ts and microsoft.ts.

  • Hosts connect through beginCalendarOAuth. The provider redirects to /api/calendar/callback, which calls completeCalendarOAuth.
  • syncCalendarConnection reads events into CalendarBusyInterval, which the availability engine treats as busy time. Google uses events.list; Microsoft uses a calendarView delta query.
  • Bookings are written to the host calendar through CalendarOperation and tracked in CalendarEventLink.
  • Tokens are encrypted with CALENDAR_CREDENTIALS_KEY.
VariablePurpose
GOOGLE_CALENDAR_CLIENT_ID, GOOGLE_CALENDAR_CLIENT_SECRETGoogle OAuth app
MICROSOFT_CALENDAR_CLIENT_ID, MICROSOFT_CALENDAR_CLIENT_SECRETMicrosoft OAuth app
CALENDAR_OAUTH_REDIRECT_URIHTTPS callback, normally https://your-host/api/calendar/callback
CALENDAR_OAUTH_STATE_SECRETSigns OAuth state; required in production
CALENDAR_CREDENTIALS_KEY32-byte base64 or 64-character hex key; required in production

Conferencing

features/integrations/conferencing/index.ts creates, updates, and deletes meetings for google_meet, microsoft_teams, and zoom.

  • Google Meet links come through each host's Google Calendar connection.
  • Microsoft Teams and Zoom use a ConferenceConnection configured with configureConferencingConnection. The operator supplies an access token, an optional refresh token, and an expiry. When the token expires, the connection moves to needs_reauth.
  • Credentials are encrypted with CONFERENCING_CREDENTIALS_KEY, which is required in production.

Payments

features/integrations/payment has two adapters: stripe and manual.

  • Stripe: configureStripePaymentProvider stores a secret key and webhook secret, encrypted with PAYMENT_CREDENTIALS_KEY (required in production). Storefront payments use Stripe Checkout; captures and refunds go through the Stripe API. Webhooks arrive at /api/payments/webhook/[providerCode] and are verified with the stored webhook secret.
  • Manual: records offline payments without contacting a provider. Onboarding demo data uses it.

Payment policy is set per event type with configureEventPaymentPolicy. A booking that requires payment cannot be confirmed or rescheduled until its payment is paid.

Email and SMS

VariablePurpose
SMTP_HOST, SMTP_PORT, SMTP_FROMRequired together for email delivery
SMTP_USER, SMTP_PASSWORD, SMTP_SECURESMTP authentication and TLS
SMTP_STORE_LINKHTTPS base URL for password reset links
SCHEDULING_SMS_ENDPOINT, SCHEDULING_SMS_TOKENGeneric HTTPS SMS gateway and bearer token for SMS reminders

Email carries invitations, password resets, booking management links, workflow email actions, and reminders. SMS is sent only by WorkflowReminder rows with channel sms, as a POST to your own SMS endpoint. There is no built-in SMS vendor adapter.

Webhooks and notifications

WebhookSubscription endpoints receive booking events signed with HMAC-SHA256 over a timestamp and the body, sent in the openfront-webhook-signature header as v1= plus the signature. NotificationSubscription rows are activated or paused with transitionNotificationSubscription, which returns the signing secret once. transitionWebhookDelivery retries a delivery. Workflow webhook actions post to their own endpointUrl.

Embeds

EmbedConfig defines a widget for one event type with theme, accent color, branding, mode, and allowedOrigins. publishEmbedConfig snapshots an EmbedRelease. Sites load /api/embed/v1.js with a slug and version, and the script mounts /embed/[slug] in an iframe. The iframe only renders for parents in the allowed origin list; in production those origins must be HTTPS.

Machine access

createSchedulingApiKey and createSchedulingOAuthClient issue team-scoped credentials with scopes such as bookings:read, availability:write, payments:write, webhooks:write, and analytics:read. OAuth clients exchange credentials at /api/oauth/token using client_credentials or refresh_token grants. Secrets are hashed with MACHINE_TOKEN_PEPPER. machineViewer reports the caller's identity and scopes.

MCP and AI chat

  • /api/mcp-transport/http is a JSON-RPC MCP endpoint. It requires a signed-in session cookie and exposes generic tools (listModels, searchModels, getFieldsForType, lookupInputType, queryData, createData, updateData, deleteData, modelSpecificSearch) that run GraphQL as that user. It has no scheduling-specific tools; everything it can do is limited by the user's access.
  • /api/completion powers dashboard AI chat through OpenRouter. With shared keys it needs dashboard access plus OPENROUTER_API_KEY and OPENROUTER_MODEL (OPENROUTER_MAX_TOKENS optional). Users can also supply their own key and model per request.

MCP and AI chat can create, update, and delete records the signed-in user is allowed to change. Data sent to a model leaves your deployment. Choose the model and provider with that in mind.

Object storage

Keystone has an S3 image store configured from S3_BUCKET_NAME, S3_REGION, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, and S3_ENDPOINT. No current list uses it.

Out of scope

  • No built-in SMS vendor, video vendor OAuth flow for Zoom or Teams, or calendar provider other than Google and Microsoft.
  • No payment adapter other than Stripe and manual. No tax, invoicing, or payout handling.
  • No inbound webhooks other than Stripe payment events and the calendar OAuth callback.

On this page