Integrating Mindbody with Lovable uses Edge Functions to call the Mindbody Public API with an API key and SiteId for classes, appointments, client check-ins, and staff management. Store your Mindbody credentials in Cloud Secrets, create an Edge Function to proxy booking and schedule requests, and build custom booking UIs for gyms, yoga studios, and wellness centers. Setup takes 45 minutes.
Why integrate Mindbody with Lovable?
Mindbody is the operating system for the wellness industry — used by over 60,000 gyms, yoga studios, Pilates centers, spas, martial arts schools, and dance studios to manage scheduling, client relationships, and payments. When businesses on Mindbody want a custom booking experience embedded in their own website or app, rather than sending clients to Mindbody's white-label widget, the Mindbody API enables building completely custom booking flows.
Common use cases include: custom class schedule pages that match a studio's brand (not the generic Mindbody widget), member portals with personalized class history and upcoming bookings, instructor bio and schedule pages, waitlist management views, and automated booking confirmation workflows. Gyms with multiple locations particularly benefit from custom multi-location views that Mindbody's standard tools don't support well.
Mindbody's API provides access to: Classes (schedules, enrollments, waitlists), Appointments (private session booking, availability checks), Clients (profiles, visit history, memberships, packages), Staff (bios, schedules, availability), Services (class types, service categories, pricing), and Sales (point of sale for adding clients to classes or selling packages). The API is REST-based with consistent authentication using your API key and the target SiteId in every request.
Integration method
Mindbody has no native Lovable connector. Integration requires Supabase Edge Functions to call the Mindbody Public API with your API key in the API-Key header and a SiteId header (or query parameter) identifying the Mindbody business site. All API calls run through Edge Functions to protect your API key. Client authentication (for booking on behalf of a specific client) uses a separate client token obtained via the client login endpoint.
Prerequisites
- A Lovable project with Cloud enabled
- A Mindbody API developer account — register at developers.mindbodyonline.com
- A Mindbody API key from the developer portal
- The SiteId of the Mindbody business site you're integrating with (found in Mindbody's software under Account → Site ID)
- Access to a Mindbody site for testing — Mindbody provides a sandbox site for developers
Step-by-step guide
Register for Mindbody API access and get credentials
Register for Mindbody API access and get credentials
Go to developers.mindbodyonline.com and create a developer account. Mindbody requires approval for API access — fill in the application form describing your use case (building a custom booking UI for a studio, etc.), your organization, and the Mindbody site(s) you'll integrate with. API access is typically approved within 1-3 business days for legitimate business integrations. Once approved, navigate to your developer portal and create an API application. Mindbody provides you with an API Key — a string that goes in the API-Key request header for all API calls. The API key grants access to the Mindbody API infrastructure; which data you can access is further controlled by the SiteId parameter that identifies the specific gym or studio. Mindbody provides a dedicated sandbox SiteId for testing: -99. This sandbox has pre-populated test data (classes, staff, clients) that you can use to test all API operations without connecting to a real studio. Test client credentials are also provided in the developer documentation. Use the sandbox throughout development and switch to the production SiteId only when deploying for a real client. Mindbody's API base URL is https://api.mindbodyonline.com/public/v6. All endpoints use this base with the specific resource path appended (e.g., /class/classes, /client/clients, /appointment/bookings). Include API-Key and SiteId headers (or SiteId as a query parameter) on every request.
Pro tip: The Mindbody sandbox SiteId is -99 (negative 99). Make sure MINDBODY_SITE_ID in Cloud Secrets is set to '-99' (the string) for development, not the number -99, as some Mindbody endpoints treat the SiteId as a string parameter.
Expected result: You have a Mindbody API key and are using the sandbox SiteId -99. You can test the API by calling GET https://api.mindbodyonline.com/public/v6/class/classes with your API key and SiteId -99 to see test class schedules.
Store Mindbody credentials in Cloud Secrets
Store Mindbody credentials in Cloud Secrets
Open your Lovable project, click '+', select 'Cloud', and expand Secrets. Add MINDBODY_API_KEY with your API key value and MINDBODY_SITE_ID with the SiteId for the studio you're integrating with (use '-99' for sandbox testing). Also add MINDBODY_API_BASE with 'https://api.mindbodyonline.com/public/v6'. For multi-site integrations where your app serves multiple Mindbody businesses, you may need to store multiple SiteIds. One approach is storing a default site ID in Cloud Secrets and accepting a dynamic site ID parameter in your Edge Function (validated against an allowed list stored in Supabase). Never allow arbitrary SiteIds from the frontend without validation — unauthorized site access could expose confidential business data. Mindbody API keys are account-level credentials that grant access to any Mindbody site that authorizes your application. Treat them with the same care as database passwords. Lovable's security infrastructure blocks approximately 1,200 hardcoded API keys per day — use Cloud Secrets for proper credential management.
Pro tip: If you're building for a single client's studio, hardcode the SiteId in Cloud Secrets. If you're building a platform that multiple studios will use, implement a site registration system where studio admins connect their Mindbody account by providing their SiteId through a setup flow, stored per-account in Supabase.
Expected result: MINDBODY_API_KEY, MINDBODY_SITE_ID, and MINDBODY_API_BASE appear in Cloud Secrets.
Create the Mindbody schedule Edge Function
Create the Mindbody schedule Edge Function
Create a Supabase Edge Function that fetches class schedules and appointment availability from Mindbody. This is typically the first data displayed when users open a booking UI — what classes are available and when. For class schedules, the GET /class/classes endpoint returns classes for a date range with all relevant details: class name, instructor name, start and end times, room name, enrollment capacity, current enrollment count (total minus remaining spots), and class description. Filter by dates using the StartDateTime and EndDateTime query parameters in ISO 8601 format. For appointment availability, the GET /appointment/staffavailabilities endpoint returns open time slots for a specific staff member and service type. Provide staff_id(s), session_type_id, start_date, and end_date parameters. Design the Edge Function to support different actions: action='classes' for the class schedule, action='staff' for staff listings, action='availability' for appointment booking slots. Return structured data with only the fields your UI needs rather than passing through Mindbody's full verbose response.
Create a Supabase Edge Function at supabase/functions/mindbody-api/index.ts. Read MINDBODY_API_KEY, MINDBODY_SITE_ID, MINDBODY_API_BASE from Deno.env. Add API-Key and SiteId headers to all requests. Support: action='classes' with start_date and end_date params — GET /class/classes; return array of {class_id, name, instructor_name, start_time, end_time, room, total_spots, available_spots, description}; action='staff' — GET /staff/staff; return array of {staff_id, first_name, last_name, bio, image_url}; action='availability' with staff_id, service_id, start_date, end_date — GET /appointment/staffavailabilities; return array of available time slots.
Paste this in Lovable chat
1// supabase/functions/mindbody-api/index.ts2import { serve } from "https://deno.land/std@0.168.0/http/server.ts";34const API_KEY = Deno.env.get("MINDBODY_API_KEY") ?? "";5const SITE_ID = Deno.env.get("MINDBODY_SITE_ID") ?? "-99";6const BASE = Deno.env.get("MINDBODY_API_BASE") ?? "https://api.mindbodyonline.com/public/v6";7const corsHeaders = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "POST, OPTIONS", "Access-Control-Allow-Headers": "Content-Type, Authorization" };89const mbFetch = (path: string, params?: Record<string, string>) => {10 const url = new URL(`${BASE}${path}`);11 if (params) Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));12 return fetch(url.toString(), { headers: { "API-Key": API_KEY, "SiteId": SITE_ID, "Content-Type": "application/json" } });13};1415serve(async (req) => {16 if (req.method === "OPTIONS") return new Response(null, { headers: corsHeaders });17 try {18 const body = await req.json();19 const { action } = body;2021 if (action === "classes") {22 const res = await mbFetch("/class/classes", { StartDateTime: body.start_date, EndDateTime: body.end_date });23 const data = await res.json();24 const classes = (data.Classes ?? []).map((c: any) => ({25 class_id: c.Id,26 name: c.ClassDescription?.Name ?? "",27 instructor_name: `${c.Staff?.FirstName ?? ""} ${c.Staff?.LastName ?? ""}`.trim(),28 start_time: c.StartDateTime,29 end_time: c.EndDateTime,30 room: c.Location?.Name ?? "",31 total_spots: c.MaxCapacity ?? 0,32 available_spots: c.TotalBooked != null && c.MaxCapacity != null ? c.MaxCapacity - c.TotalBooked : null,33 }));34 return new Response(JSON.stringify({ classes }), { headers: { ...corsHeaders, "Content-Type": "application/json" } });35 }3637 if (action === "staff") {38 const res = await mbFetch("/staff/staff");39 const data = await res.json();40 const staff = (data.StaffMembers ?? []).map((s: any) => ({41 staff_id: s.Id,42 first_name: s.FirstName,43 last_name: s.LastName,44 bio: s.Bio ?? "",45 image_url: s.ImageURL ?? "",46 }));47 return new Response(JSON.stringify({ staff }), { headers: { ...corsHeaders, "Content-Type": "application/json" } });48 }4950 return new Response(JSON.stringify({ error: "Unknown action" }), { status: 400, headers: corsHeaders });51 } catch (err) {52 return new Response(JSON.stringify({ error: err.message }), { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } });53 }54});Pro tip: Mindbody class IDs are integers and enrollment counts can change rapidly when classes are popular. Refresh class availability data every few minutes on the schedule page rather than caching for long periods — showing 3 spots available when the class is actually full leads to booking failures.
Expected result: The mindbody-api Edge Function returns class schedules and staff data from the Mindbody sandbox site. Calling action='classes' with today's date returns available classes with instructor names and spot counts.
Implement class booking and client authentication
Implement class booking and client authentication
Booking classes in Mindbody requires client authentication — you need a client-specific token to book on behalf of a user. The client token is obtained by calling POST /client/addclienttosession or using the staff token for administrative bookings. For consumer-facing apps where clients book their own classes, implement client login: accept the client's Mindbody email and password in your Lovable app, send them to an Edge Function that calls POST /usertoken/issue (or POST /client/clienttokenissue depending on the API version) to obtain a client token, and store this token with the user's Supabase account for subsequent booking calls. For class booking, call POST /class/addclienttoclass with the class_id, client_id, and the client's access token. For appointment booking, use POST /appointment/bookappointment with staff_id, appointment_type_id, start_date_time, and duration. Handle booking errors gracefully: Mindbody returns specific error codes for 'class is full', 'client already booked', 'insufficient membership credits', and 'outside cancellation window'. Display user-friendly messages for each case rather than showing raw API errors.
Extend the mindbody-api Edge Function with booking actions: action='client-login' with email and password — POST to Mindbody /usertoken/issue to get client token; store token in Supabase with user_id; return {success: true}. action='book-class' with class_id and user_id — get user's Mindbody client token from Supabase; POST to /class/addclienttoclass; return {success, booking_id, confirmation_message}. action='cancel-booking' with visit_id and user_id — POST to /class/removeclientfromclass. Add clear error messages for full class, already booked, and insufficient credits scenarios.
Paste this in Lovable chat
Pro tip: Mindbody client tokens expire after a period of inactivity (typically 24 hours). Store the token with an expiry timestamp and re-authenticate when expired. Alternatively, implement a silent re-authentication flow that catches 401 errors and attempts to log in again using stored (but never plaintext) client credentials — note that storing client passwords requires careful security considerations.
Expected result: Clients can log in with their Mindbody credentials to get a client token. The Book Class button calls the Edge Function to add them to the class in Mindbody. Booking confirmations and error messages display correctly.
Common use cases
Custom gym class schedule and booking page
A fitness studio builds a custom class schedule page that matches their brand instead of embedding Mindbody's generic widget. An Edge Function fetches the weekly class schedule from Mindbody and returns class names, instructors, times, enrollment counts, and available spots. Users can view the schedule and book classes directly through a custom interface.
Build a custom class schedule page for a yoga studio. Create an Edge Function that fetches this week's class schedule from Mindbody using the /class/classes endpoint with the studio's SiteId. Return class name, instructor, start time, duration, room location, spots remaining, and total spots. Display as a weekly calendar view. Add a Book button on each class that calls an Edge Function to book the class for the logged-in user using their Mindbody client token. Show a confirmation modal after successful booking.
Copy this prompt to try it in Lovable
Member portal with booking history
A gym member portal lets members view their upcoming bookings, past visit history, and current membership status from Mindbody. An Edge Function authenticates the member with their Mindbody client credentials, then fetches their visit history and upcoming bookings. Members can cancel upcoming bookings directly from the portal.
Build a member portal. Add a 'Sign in with Mindbody' flow that calls an Edge Function to authenticate the member with their Mindbody email/password using the client login endpoint. Store the returned client token. Build a dashboard showing: upcoming bookings from /client/clientvisits with status='Booked', visit history from the last 30 days, current membership name and expiry date from /client/clientmemberships. Add a Cancel button on upcoming bookings that calls the booking cancellation endpoint.
Copy this prompt to try it in Lovable
Personal trainer appointment booking system
A personal training studio builds a booking portal for scheduling private sessions with specific trainers. An Edge Function fetches trainer availability from Mindbody's appointment scheduling API and displays available time slots. Clients select a trainer, date, and time, and the Edge Function books the appointment in Mindbody.
Build a personal training booking system. Fetch all active staff from Mindbody's /staff/staff endpoint and display them as cards with photo, bio, and specialties. When a trainer is selected, fetch their available appointment slots from /appointment/staffavailabilities for the next 7 days. Show a calendar with available time slots. When a slot is selected, call the appointment booking Edge Function with the staff_id, time, service_id, and client_token. Show booking confirmation with appointment details.
Copy this prompt to try it in Lovable
Troubleshooting
API returns 'ApiKeyNotFound' or 401 status on all requests
Cause: The MINDBODY_API_KEY Cloud Secret is missing, has extra whitespace, or the API key isn't activated for the SiteId you're targeting. Mindbody API keys may require the site owner to authorize your application before you can access their data.
Solution: Verify the API-Key header value in Cloud Logs matches the exact key from your Mindbody developer portal (no extra spaces or newlines). For non-sandbox SiteIds, confirm the studio owner has connected your API application to their Mindbody account. Test with the sandbox SiteId -99 first to confirm the API key itself is valid.
Class booking fails with 'Insufficient payment method' error
Cause: Mindbody requires clients to have a valid pricing option (class pack, membership, or drop-in payment) to book a class. If the client has no active payment method or their class pack is empty, booking fails even if spots are available.
Solution: Before attempting to book, call the /client/requiredclientfields and /client/clientmemberships endpoints to check the client's payment status. Display a clear 'You need to purchase a class pack to book' message rather than a generic error. Consider adding a flow that directs clients to purchase passes through Mindbody's payment pages.
Class schedule shows empty after switching from sandbox to production SiteId
Cause: The production SiteId may not have classes scheduled in the date range you're querying, or the studio's schedule may use different time formats, time zones, or category structures than the sandbox.
Solution: Test the production API calls directly in Cloud Logs with a broad date range (current month). Verify the StartDateTime and EndDateTime parameters include the studio's timezone-aware times — Mindbody uses the site's local timezone. Also confirm the API key has been authorized by the production studio owner.
Best practices
- Cache class schedules in Supabase and refresh every 5 minutes — class data changes slowly and caching dramatically reduces API calls while keeping enrollment counts reasonably current.
- Always check available spots before showing a Book button — don't show Book for classes with 0 available spots, and refresh availability after successful bookings to update the displayed count.
- Handle the Mindbody sandbox SiteId (-99) gracefully in your Edge Function — add a check that defaults to sandbox in development and uses the production SiteId in production, controlled by an environment variable.
- Never store client Mindbody passwords in your app — obtain a client token at login time and store only the token. Prompt re-authentication when the token expires.
- Implement booking confirmation emails using Lovable's built-in email or Resend Edge Function — Mindbody sends its own confirmation but a custom branded email from your app improves the member experience.
- For high-traffic studios where classes fill up quickly, implement an optimistic UI that shows Booking... immediately and rolls back if the API returns a full-class error.
- Log all booking attempts (success and failure) in a Supabase bookings_log table with the error code — this data helps identify common failure patterns and improve the user experience.
Alternatives
Acuity Scheduling is a general-purpose appointment booking system with simpler API setup; choose Acuity when you need flexible scheduling beyond fitness-specific use cases.
Fitbit API provides personal health data from wearables; use Fitbit alongside Mindbody when you want to combine class attendance with biometric data for members.
Calendly is simpler for general appointment scheduling but lacks fitness industry features like class packs, membership tracking, and waitlists that Mindbody specializes in.
Frequently asked questions
Can I use Mindbody API without the studio owner's permission?
For the sandbox SiteId -99, you can use the API freely for development. For production SiteIds, the studio's Mindbody account owner must authorize your API application through their Mindbody account settings. You can't access a real studio's live data without their explicit authorization. This is by design — it prevents unauthorized apps from scraping business and client data.
Does Mindbody API support all business types (gyms, yoga studios, spas)?
Yes — Mindbody serves fitness, wellness, and beauty businesses including gyms, yoga studios, Pilates, martial arts, massage, spas, salons, and more. The API endpoints cover all business types, though some features (like appointment booking vs. class booking) are more relevant to certain business types. The SiteId identifies the specific business, and the available classes and services are whatever that business has configured in Mindbody.
Can I build a multi-studio booking app that works across multiple Mindbody businesses?
Yes — your API key can access multiple SiteIds if each studio authorizes your application. Store each studio's SiteId in Supabase and pass the appropriate SiteId in your Edge Function requests when a user selects a studio. This enables building a marketplace or aggregator app that shows classes from multiple studios in one view.
How do I handle Mindbody waitlists?
When a class is full, clients can add themselves to a waitlist using the /class/addclienttoclass endpoint with the 'waitlist_available' parameter checked. Mindbody automatically moves waitlisted clients into the class if a spot opens up. You can show waitlist status by checking if available spots is 0 but the class has a waitlist open, and adjust your Book button to say 'Join Waitlist' in that case.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation