Database Schema
The FluentBooking database is designed for high performance, maintaining a clean separation between core scheduling data, host availability, and extensibility via metadata.
Core Entity Relationships
The following diagram illustrates the primary relationships between the core entity tables in FluentBooking.

Schema Overview
The FluentBooking schema is built around these core concepts:
- Calendars & Events: Top-level containers for scheduling rules and specific appointment types.
- Bookings: The central ledger for all scheduled appointments, including customer data and status.
- Availability & Rules: Stored in a polymorphic meta system to allow for both global and event-specific overrides.
- Multi-Host Management: Pivot-based assignment for team scheduling, round-robin, and collective events.
- Activity & Auditing: Detailed logs for every state change or notification event related to a booking.
- Pro Extensions: Additional tables for Orders and Transactions to handle paid scheduling.
Key Design Principles
- JSON Configuration: Complex settings for events and calendars are stored as JSON for maximum flexibility without schema changes.
- Polymorphic Meta: We use a unified
fcal_metatable for various object types (Calendars, Events) to keep the core schema lean. - Audit Trail: Every significant booking event is logged in
fcal_booking_activityfor debugging and customer support. - Performance Indexing: Strategic composite indexes are placed on time-based columns (
start_time,end_time) and foreign keys for rapid availability lookups. - UUID / Hash Security: Public identifiers are used for booking hashes and calendar slugs to prevent ID enumeration.
Database Tables
All tables are prefixed with fcal_ (or your custom WordPress prefix).
fcal_calendars
The master table for calendars.
id: Primary keyhash: Unique public identifieruser_id: Owner's WP User IDaccount_id: Associated integration account IDparent_id: Parent calendar ID (teams)title: Calendar nameslug: Public URL slugmedia_id: Featured image IDdescription: Calendar descriptionsettings: (Serialized) Additional configurationsstatus:active,inactiveorexpiredtype:simple(individual),team, oreventevent_type: Primary event categoryaccount_type:free/provisibility:public/adminauthor_timezone: Host's default timezonemax_book_per_slot: Default guests limit per calendarcreated_at: Record creation timestampupdated_at: Record last update timestamp
fcal_calendar_events
Represents bookable event types (Slots).
id: Primary keyhash: Unique public identifieruser_id: Creator's WP User IDcalendar_id: Parent calendar IDduration: Length of event in minutestitle: Event nameslug: Event public slugmedia_id: Featured image IDdescription: Event descriptionsettings: (Serialized) Additional configurations stored. Examples include buffer times, available date ranges, date_overrides, booking limits, etc.availability_type:existing_schedule/customavailability_id: ID for existing schedule availabilitystatus:active/inactive/draft/expiredtype:free/paidcolor_schema: Display colorlocation_type: Primary location typelocation_heading: Custom label for locationlocation_settings: (Serialized) Multi-location configevent_type:single,group,single_event,group_event,round_robin,collectiveis_display_spots: Show/hide remaining spots of group eventmax_book_per_slot: Max guests limit of group eventcreated_at: Record creation timestampupdated_at: Record last update timestamp
fcal_bookings
Stores all appointment records.
id: Primary keyhash: Public meeting identifiercalendar_id: Related calendar IDevent_id: Related event IDgroup_id: Group ID for multi-seat bookingsparent_id: Parent ID for repeating bookingshost_user_id: Assigned primary hostperson_user_id: Attendee WP User ID (if logged in)person_contact_id: CRM contact IDfcrm_id: FluentCRM subscriber IDperson_time_zone: Attendee's timezonestart_time: UTC startend_time: UTC endslot_minutes: Booking durationfirst_name,last_name,email,phone: Attendee infomessage: Meeting notes for userinternal_note: Internal notes for admincountry: Attendee's countryip_address: Attendee's IP addressbrowser: Attendee's browser infodevice: Attendee's device infoother_info: (Serialized) Custom form field datalocation_details: (Serialized) Selected booking location infocancelled_by: WP User ID who cancelled the bookingstatus:scheduled,pending,cancelled,completed,rejected,rescheduled,reserved,no_showsource:web/admin/integrationbooking_type:scheduling,eventevent_type:single,group,round_robin,collective, etc.payment_status:pending,paid,partially-paid,partially-refundedpayment_method:stripe,paypal,offline, etc.source_url: URL of the page where the booking was madesource_id: ID of the source (form, post, etc.)utm_source,utm_medium,utm_campaign,utm_term,utm_content: Tracking paramscreated_at: Record creation timestampupdated_at: Record last update timestamp
fcal_booking_meta
Polymorphic key-value storage for specific booking data (e.g., custom fields).
id: Primary keybooking_id: Foreign keymeta_key: Meta keyvalue: (Serialized) Meta valuecreated_at: Record creation timestampupdated_at: Record last update timestamp
fcal_booking_activity
Detailed audit log for all booking actions.
id: Primary keybooking_id: Related bookingparent_id: Parent activity ID (nested)created_by: WP User ID of actorstatus: Status of action (open,failed,success,closed)type:info,success,error,note,email_log, etc.title,description: Log detailscreated_at: Record creation timestampupdated_at: Record last update timestamp
fcal_booking_hosts
Pivot table linking multiple hosts to a single booking.
id: Primary keybooking_id: Related bookinguser_id: Assigned host's WP User IDstatus:confirmed,pending,declinedcreated_at: Record creation timestampupdated_at: Record last update timestamp
fcal_meta
Polymorphic storage for various objects.
id: Primary keyobject_type:Calendar,calendar_event,availability,user_meta,integration, etc.object_id: Related IDkey: Meta keyvalue: (Serialized) Meta valuecreated_at: Record creation timestampupdated_at: Record last update timestamp
fcal_orders Pro
Financial orders table for paid bookings.
id: BIGINT UNSIGNED, Primary key, Auto-incrementstatus: VARCHAR(20), Order status —draft,pending,completed,failed,refunded,cancelledparent_id: BIGINT UNSIGNED, Related booking IDorder_number: VARCHAR(255), Order display/reference numbertype: VARCHAR(20), Order type —sale,refund,subscription(default'sale')customer_id: BIGINT UNSIGNED, Related customer WP User IDpayment_method: VARCHAR(100), Payment gateway key (e.g.,stripe,paypal,offline)payment_mode: VARCHAR(100), Payment environment —test/livepayment_method_type: VARCHAR(100), Further method details (e.g.,card,bank_transfer)payment_method_title: VARCHAR(100), Human-readable payment method labelcurrency: VARCHAR(10), ISO currency codesubtotal: DECIMAL(18,9), Order subtotal before discounts/taxdiscount_tax: DECIMAL(18,9), Discount tax amountdiscount_total: DECIMAL(18,9), Discount pre-taxshipping_tax: DECIMAL(18,9), Shipping taxshipping_total: DECIMAL(18,9), Shipping costtax_total: DECIMAL(18,9), Total tax amounttotal_amount: DECIMAL(18,9), Final order total (after all fees/discounts)total_paid: DECIMAL(18,9), Amount paid towards this orderrate: DECIMAL(18,9), Conversion rate if multi-currency (default 1)note: TEXT, Public order noteip_address: TEXT, Payer IP addresscompleted_at: DATETIME, When marked completed (nullable)refunded_at: DATETIME, When refunded (nullable)uuid: VARCHAR(100), Unique identifier (for external integrations)created_at: TIMESTAMP, Created atupdated_at: TIMESTAMP, Last updated at
Indexes:
type(order type)order_number(191 length), for quick lookupcustomer_id(customer reference)
fcal_order_items Pro
Detailed line items for financial orders.
id: Primary keyorder_id: Parent order IDbooking_id: Associated booking IDitem_name: Display titletype:single,discount,taxquantity,item_price,item_total: Financial datarate: Currency conversion rateline_meta: (Serialized) Additional item metadatacreated_at: Record creation timestampupdated_at: Record last update timestamp
fcal_transactions Pro
Gateway-specific transaction logs.
id: BIGINT(20) UNSIGNED, Primary key, Auto-incrementobject_id: BIGINT UNSIGNED, Related order ID (not null, default0)object_type: VARCHAR(100), Object type (not null, default'')transaction_type: VARCHAR(255), Transaction type —one_time,subscription,refund(default'one_time')subscription_id: INT(11), Related subscription ID (nullable)card_last_4: INT(4), Card last 4 digits (nullable)card_brand: VARCHAR(255), Card brand (nullable)vendor_charge_id: VARCHAR(192), Gateway reference ID (not null, default'')payment_method: VARCHAR(100), Payment gateway/method (not null, default'')payment_method_type: VARCHAR(100), Further payment method details (not null, default'')status: VARCHAR(20), Payment status —succeeded,failed,pending,refunded(not null, default'')total: DECIMAL(18,9), Total transaction amount (not null, default0.000000000)rate: DECIMAL(10,5), Currency conversion rate (not null, default1.00000)uuid: VARCHAR(100), Unique identifier (not null, default'')meta: JSON, Additional metadata (nullable)created_at: TIMESTAMP, Created at (nullable)updated_at: TIMESTAMP, Last updated at (nullable)
Indexes:
vendor_charge_id(first 64 chars), for gateway lookupspayment_methodstatusobject_id