|

Openfront Scheduling

Self-hosted booking pages and team scheduling with event types, availability, bookings, routing forms, payments, calendars, workflows, and embeds.

Openfront Scheduling is a self-hosted booking and team-scheduling application for appointment businesses such as studios, clinics, agencies, and consultancies. A team publishes bookable event types with hosts, weekly schedules, intake questions, buffers, optional payment, conferencing, and room or equipment requirements. Customers book on the public booking pages, through an embed on another site, or after answering a routing form. Hosts and team admins then confirm, decline, reschedule, cancel, complete, or mark bookings as no-shows from the operator dashboard.

The source lives at github.com/openshiporg/openfront-scheduling. A hosted demo runs at scheduling.openship.org.

Calendar sync, conferencing, Stripe payments, SMTP email, SMS, and outbound webhooks call external providers only after you configure their credentials. Until then, those paths fail at the point of use and the booking flows that do not depend on them keep working.

What the codebase contains

The application uses Next.js 16 (App Router, React 19), Keystone 6 with a GraphQL API at /api/graphql, Prisma, and PostgreSQL.

DirectoryContents
features/keystone/models62 Keystone lists covering identity and teams, event types and availability, bookings, routing, workflows, payments, calendars, conferencing, webhooks, embeds, machine access, data jobs, and analytics
features/keystone/mutationsNamed GraphQL commands such as createStorefrontBooking, transitionBooking, inviteTeamMember, configureEventPaymentPolicy, and publishEmbedConfig
features/keystone/libAvailability engine, host assignment, routing engine, workflow engine, payment transitions, and the scheduling outbox worker
features/platformOperator dashboard slices: bookings, event types, availability, clients, payments, team, resources, routing forms, workflows, store settings, integrations, webhooks, embeds, API keys, data jobs, analytics, and onboarding
features/storefrontPublic booking pages, guest booking management, customer account pages, and the embed widget screens
features/integrationsCalendar (Google, Microsoft), conferencing (Google Meet, Microsoft Teams, Zoom), payment (Stripe, manual), and reminder/webhook delivery adapters
features/mcpAn MCP endpoint with generic GraphQL schema and data tools that run under the signed-in user's session

Operator surfaces

Operators sign in at /dashboard. Scheduling work happens under /dashboard/platform/*: an overview, a bookings list and booking detail, event types, availability schedules, clients, payments, team members and invitations, resources and managed templates, routing forms, workflows and reminders, storefront settings, integrations, webhooks, embeds, API keys, data jobs, and analytics. The generic Keystone list and item screens stay available for permitted records. See External dashboards for the full route table.

Storefront

The public application shows one team's booking pages: the home page at /, the event list at /book, an event page with time selection at /book/[slug], host pages, routing forms at /routes, an embed gallery at /embed, and the iframe widget at /embed/[slug]. Guests manage a booking through a private link at /book/manage. Customers with an account see their history at /account. See External storefronts.

Onboarding

On an empty database, /dashboard/init creates the first administrator. The dashboard onboarding dialog then runs bootstrapSchedulingOnboarding in one of two modes. Demo mode creates the fictional Northstar Studio team with sample hosts, a schedule, event types, questions, a routing form, an embed, a reminder, a webhook, a manual payment provider, and sample bookings. Merchant mode creates your own team from a business name, slug, time zone, owner display name, and logo, with sample data optional. See Getting started.

Ownership and tenancy

Team is the tenant root. Almost every list is team-owned through teamOwnedListAccess: reads are scoped to teams where the user has an active Member row, and create, update, and delete need an owner or admin membership in the owning team. Hosts can confirm and decline bookings they are assigned to. Viewers can read. A record cannot be moved from one team to another, even by someone who manages both. Lists marked command-only (for example Booking, Member, Resource, ApiKey, PaymentBooking) reject raw create, update, and delete and change only through named mutations that take an idempotencyKey and write an audit event. The global Role flags control dashboard access, people and role administration, and onboarding. They do not bypass team scoping.

On this page