Connect Retool to Mindbody by creating a REST API Resource pointing to the Mindbody Public API (api.mindbodyonline.com/public/v6), authenticated with your API key and site credentials. Build fitness studio operations dashboards that display class schedules, client bookings, membership status, and revenue data — giving studio managers a consolidated operational view that goes beyond Mindbody's built-in reporting.
| Fact | Value |
|---|---|
| Tool | Mindbody |
| Category | Other |
| Method | REST API Resource |
| Difficulty | Intermediate |
| Time required | 25 minutes |
| Last updated | April 2026 |
Why Connect Retool to Mindbody?
Fitness studio owners and operations managers use Mindbody to run their day-to-day business, but Mindbody's native reporting has fixed templates that don't always answer the specific questions managers need to track — which instructors have the highest class fill rates, which membership tiers are growing fastest, or which clients haven't visited in 30 days and need a re-engagement outreach. Connecting Mindbody to Retool unlocks the underlying data through the Public API and enables building exactly the dashboards and panels the business needs.
Studio operations teams benefit from custom dashboards that combine Mindbody class schedule data with internal staffing records, showing instructor schedules alongside their payroll information. Marketing teams build client re-engagement panels that pull Mindbody clients by last visit date and export lists for email campaigns. Finance teams create revenue tracking dashboards that aggregate Mindbody sales data by membership type, service, and period — with drill-down capabilities that Mindbody's native reports don't provide.
Mindbody's Public API v6 covers all major business objects: classes and schedules, appointments, clients and memberships, staff, products, and sales. Authentication uses an API key plus a site-specific user token for staff-level operations. Note that API access requires a Mindbody subscription tier that includes API access — check with Mindbody's team to confirm your plan includes the Public API.
Integration method
Retool connects to Mindbody through a REST API Resource targeting the Mindbody Public API v6. Authentication requires a Mindbody API key (obtained from the Mindbody developer portal) plus a site-specific staff user token for endpoints that require authentication on behalf of a staff user. All requests are proxied server-side through Retool's backend, keeping API credentials off the browser. Queries target Mindbody's endpoint groups for classes, clients, sales, staff, and appointments, with JavaScript transformers reshaping responses for Retool's Table and Chart components.
Prerequisites
- A Retool account (Cloud or self-hosted) with permission to create Resources
- A Mindbody subscription that includes Public API access — contact Mindbody support to confirm your plan includes the API and to request an API key from the Mindbody Developer Portal at developers.mindbodyonline.com
- A Mindbody API key (provided after registering your application in the developer portal) and your Mindbody Site ID (found in your Mindbody business settings)
- A Mindbody staff user account with appropriate permissions to the data you need to query — the API uses this account's credentials to scope what data is accessible
- Familiarity with Mindbody's data model: Sites, Classes, Clients, Memberships, Staff, and the difference between classes (group) and appointments (one-on-one)
Step-by-step guide
Register your application and obtain a Mindbody API key
Mindbody API access requires registering an application in their developer portal to receive an API key. Go to developers.mindbodyonline.com and create an account or log in. Navigate to My Apps and click New Application. Provide your application name (e.g., 'Retool Integration'), description, and the intended use case (internal business operations dashboard). Submit the registration. Mindbody reviews API applications, and approval may take a few business days for new accounts. Once approved, you will receive an API key — a long string that you include in every API request. Copy this key and store it securely. Your Site ID is a numeric identifier for your specific Mindbody business location. Find it in your Mindbody account under Settings → Business Information, or by looking at the URL when logged into your Mindbody account (it typically appears as a numeric parameter). The Site ID is required in every API request and scopes all data to your business. For testing, Mindbody provides a sandbox environment with test data at a separate sandbox API URL. If sandbox access is available for your account, use it to test your Retool configuration before pointing at the production API. The sandbox URL is typically: https://api.mindbodyonline.com/sandbox/v6/ Note: Some Mindbody API endpoints require a UserToken in addition to the API key — specifically, any operation that needs to act on behalf of a specific staff member (like creating bookings or viewing restricted client data). You obtain a UserToken by calling the /usertoken/issue endpoint with the staff user's credentials. Plan which endpoints your dashboards will use and whether they require a UserToken.
Pro tip: Create a dedicated Mindbody staff account for API access rather than using your personal owner account. Give this account the minimum permissions needed for the dashboards you are building. This scopes API data access appropriately and makes it easy to audit or revoke API access independently of your main account.
Expected result: You have a Mindbody API key, your business's Site ID, and optionally a UserToken for staff-level operations. You have confirmed whether your dashboards need UserToken authentication by reviewing the Mindbody API documentation for the specific endpoints you will use.
Create the Mindbody REST API Resource in Retool
Navigate to the Resources tab in Retool and click Add Resource. Select REST API from the resource type list. Configure the resource: - Name: 'Mindbody API' - Base URL: https://api.mindbodyonline.com/public/v6 For authentication, Mindbody does not use a standard Bearer Token or Basic Auth pattern — instead, it requires custom headers. Select No Authentication from the Auth dropdown and configure the credentials as Default Headers: Add the following headers that will be sent with every request: - Header 1 — Key: Api-Key, Value: YOUR_MINDBODY_API_KEY - Header 2 — Key: SiteId, Value: YOUR_SITE_ID (as a string, e.g., '-99' for sandbox or '12345' for production) - Header 3 — Key: Content-Type, Value: application/json For endpoints requiring a UserToken, you will add the Authorization header at the query level rather than the resource level (since not all endpoints require it). In the query editor, add a header: Authorization: [your UserToken value]. Click Save Changes. Verify the resource by creating a test query: - Method: GET - Path: /site/sites - No additional parameters needed for this endpoint Run the query. A successful response returns site information including your business name and contact details, confirming the API key and SiteId headers are being sent correctly.
Pro tip: For Mindbody's sandbox environment, use SiteId: -99 (the standard sandbox site ID) and the sandbox API base URL: https://api.mindbodyonline.com/sandbox/v6. Always test new query configurations against the sandbox before running against your production site to avoid creating test bookings or altering live data.
Expected result: The Mindbody REST API Resource appears in the Resources list with the Api-Key and SiteId headers configured as defaults. A test GET to /site/sites returns your business information, confirming the authentication headers are correctly configured.
Query class schedules and build a schedule management table
The Mindbody /class/classes endpoint returns the schedule of group fitness classes for a date range. This is the primary endpoint for building schedule management and fill rate dashboards. Create a new query using the Mindbody API resource: - Method: GET - Path: /class/classes - URL Parameters: - StartDateTime: {{ dateRangePicker.startDate + 'T00:00:00' }} - EndDateTime: {{ dateRangePicker.endDate + 'T23:59:59' }} - HideCancelledClasses: true - Limit: 100 The response returns a Classes array where each class object contains: Id, ClassDescription (with Name, Id), StartDateTime, EndDateTime, Staff (with Name, Id), Location (with Name), MaxCapacity, TotalBooked, TotalBookedWaitlist, IsCancelled, and IsSubstitute fields. Write a JavaScript transformer that maps the Classes array into a flat format with computed fields. Calculate the fill rate as a percentage (TotalBooked / MaxCapacity * 100). Add a 'status' field based on fill rate thresholds (over-enrolled, healthy, under-enrolled). Format the StartDateTime into a readable date and time. Drag a Table component onto the canvas. Set its data to the transformer output. Configure columns for class name, instructor, date, time, enrolled/capacity (formatted as '15/20'), fill rate percentage, and waitlist count. Add a percentage bar column for visual fill rate representation if your Retool version supports it.
1// JavaScript transformer for Mindbody class schedule response2const classes = data?.Classes || [];34return classes.map(cls => {5 const startDt = new Date(cls.StartDateTime);6 const fillRate = cls.MaxCapacity > 07 ? Math.round((cls.TotalBooked / cls.MaxCapacity) * 100)8 : 0;910 return {11 id: cls.Id,12 class_name: cls.ClassDescription?.Name || 'Unknown Class',13 instructor: cls.Staff?.Name || 'Staff TBD',14 date: startDt.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' }),15 time: startDt.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }),16 enrolled: cls.TotalBooked || 0,17 capacity: cls.MaxCapacity || 0,18 enrolled_of_capacity: `${cls.TotalBooked || 0} / ${cls.MaxCapacity || 0}`,19 fill_rate: fillRate,20 fill_rate_label: fillRate + '%',21 waitlist: cls.TotalBookedWaitlist || 0,22 location: cls.Location?.Name || '',23 status: fillRate >= 90 ? 'Full'24 : fillRate >= 70 ? 'Healthy'25 : fillRate >= 40 ? 'Moderate'26 : 'Low'27 };28});Pro tip: Add a Stat component row above the class table showing aggregate metrics for the selected date range: total classes scheduled, average fill rate, and total spots filled vs total capacity. These summary numbers are what studio managers need at a glance without scrolling through the full table.
Expected result: A Table displays the class schedule for the selected date range with fill rate data. Classes are sorted by date and time. The fill rate column shows percentages, and over-capacity or under-enrolled classes are visually distinguished.
Query client data and build a client management panel
The Mindbody /client/clients endpoint returns a paginated list of clients with their profile and membership information. Use this to build client management panels for retention, re-engagement, and membership tracking. Create a new query using the Mindbody API resource: - Method: GET - Path: /client/clients - URL Parameters: - SearchText: {{ clientSearchInput.value || '' }} (searches name and email) - IsProspect: false (set to true to search prospects instead of active clients) - Limit: 50 - Offset: {{ (clientTable.pageIndex || 0) * 50 }} Note: The /client/clients endpoint may require a UserToken depending on your Mindbody plan and permission settings. If you receive a 401 or 403 error, add an Authorization header to this specific query with the UserToken obtained from the /usertoken/issue endpoint. The response returns a Clients array with Id, FirstName, LastName, Email, MobilePhone, LastModifiedDateTime, PhotoUrl, and ClientRelationships fields. To get membership information, you need a separate call to /client/clientservices for each client — or query /client/contactlogs for communication history. Write a transformer that formats the client list with computed fields: full name (FirstName + LastName), formatted last visit date, and a days-since-last-contact calculated from LastModifiedDateTime. Display in a Table with pagination using Retool's built-in table pagination bound to the query's Offset parameter.
1// JavaScript transformer for Mindbody client list response2const clients = data?.Clients || [];34return clients.map(client => {5 const lastModified = client.LastModifiedDateTime6 ? new Date(client.LastModifiedDateTime)7 : null;8 9 const daysSince = lastModified10 ? Math.floor((Date.now() - lastModified) / (1000 * 60 * 60 * 24))11 : null;1213 return {14 id: client.Id,15 name: `${client.FirstName || ''} ${client.LastName || ''}`.trim() || 'Unknown',16 email: client.Email || '',17 phone: client.MobilePhone || client.HomePhone || '',18 last_modified: lastModified19 ? lastModified.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })20 : 'Never',21 days_since_contact: daysSince,22 engagement_status: daysSince === null ? 'Unknown'23 : daysSince <= 14 ? 'Active'24 : daysSince <= 30 ? 'At Risk'25 : 'Lapsed'26 };27});Pro tip: Mindbody's /client/clients endpoint can return a large number of records. Use Limit and Offset parameters for pagination and connect the Offset to Retool's Table component's pageIndex property for seamless server-side pagination. Avoid requesting all clients at once — for studios with thousands of clients, this will time out.
Expected result: A searchable, paginated Table shows clients with name, email, and engagement status. The search input filters by name or email in real-time via the Mindbody API's SearchText parameter. Clicking a client row shows a detail panel with full profile information.
Build a sales revenue dashboard with Mindbody sales data
The Mindbody /sale/sales endpoint returns transaction records for sales made at your studio. Use this to build revenue dashboards that aggregate sales by category, period, and payment method. Create a query using the Mindbody API resource: - Method: GET - Path: /sale/sales - URL Parameters: - StartSaleDateTime: {{ monthPicker.startDate + 'T00:00:00' }} - EndSaleDateTime: {{ monthPicker.endDate + 'T23:59:59' }} - Limit: 200 Note: The /sale/sales endpoint requires a UserToken (staff authorization) in the Authorization header for most Mindbody configurations. Obtain the UserToken by calling POST /usertoken/issue with the staff account's Username, Password, and your SiteId. The response returns a Sales array where each sale has: Id, SaleDateTime, ClientId, SaleItems (array of line items with each item's Description, ServiceName, PaymentMethod, Revenue, and Quantity), and TotalPaid. Write a transformer that flattens the nested SaleItems structure into individual line-item rows, extracting the service category from ServiceName, summing revenues by category, and formatting the total amounts as currency. Bind the aggregated totals to Stat components showing total revenue, revenue by category, and number of transactions. Bind the detailed sales rows to a Table for drill-down review. Add a Retool Chart component displaying revenue by week as a bar chart, using a secondary transformer that groups the sales data by week and sums the revenue. This gives studio owners the trend view alongside the detailed transaction data.
1// JavaScript transformer to flatten Mindbody sales into line items2const sales = data?.Sales || [];34// Flatten each sale's SaleItems into individual rows5const lineItems = [];6sales.forEach(sale => {7 const saleDate = new Date(sale.SaleDateTime);8 const items = sale.SaleItems || [];9 items.forEach(item => {10 lineItems.push({11 sale_id: sale.Id,12 date: saleDate.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }),13 client_id: sale.ClientId || '',14 description: item.Description || item.ServiceName || 'Unknown Item',15 category: item.ServiceName?.includes('Membership') ? 'Membership'16 : item.ServiceName?.includes('Class') ? 'Class Package'17 : item.ServiceName?.includes('Retail') ? 'Retail'18 : 'Other',19 payment_method: item.PaymentMethod || 'Unknown',20 quantity: item.Quantity || 1,21 amount: parseFloat(item.Revenue || 0),22 amount_display: `$${parseFloat(item.Revenue || 0).toFixed(2)}`23 });24 });25});2627return lineItems;Pro tip: For the UserToken required by the /sale/sales endpoint, create a pre-load JavaScript query that calls POST /usertoken/issue with staff credentials stored in Retool Configuration Variables. Store the returned token in a state variable and reference it in the Authorization header of your sales queries: {{ userTokenQuery.data.AccessToken }}.
Expected result: A revenue dashboard shows Stat components for total revenue and revenue by category, a bar chart of weekly revenue trends, and a detailed transaction Table. The month picker filters all components to the selected time period.
Common use cases
Build a class schedule and fill rate monitoring dashboard
Create a Retool dashboard that queries the Mindbody API for the current week's class schedule, including class name, instructor, time, room, max capacity, and current enrollment count. Display fill rates as a percentage and highlight classes that are at capacity (for waitlist management) or significantly under-enrolled (for promotion decisions). Studio managers use this as their daily operational view.
Build a class schedule dashboard with a date range picker defaulting to the current week. Query Mindbody's /class/classes endpoint for classes in the date range. Display results in a Table with columns for class name, instructor, date/time, enrolled count, capacity, fill rate percentage, and waitlist count. Color-code rows: green for 75%+ full, yellow for 50-75%, red for under 50% to make under-enrolled classes immediately visible.
Copy this prompt to try it in Retool
Create a client membership and engagement tracking panel
Build a Retool panel for client success managers that surfaces client data including membership type, status, last visit date, and total visits. Use filters to identify clients with lapsed memberships, clients who haven't visited in 30+ days, and clients approaching their membership renewal date. The panel enables proactive outreach before clients cancel, improving retention rates.
Create a client retention panel that queries the Mindbody /client/clients endpoint for all active clients with their visit history. Add filters for membership status (active, expired, suspended) and last visit date range. Display a Table with client name, membership type, last visit, total visits, and membership expiry date. Include a 'Days Since Last Visit' computed column that highlights clients in red if over 30 days, yellow if 15-30 days.
Copy this prompt to try it in Retool
Build a revenue and sales reporting dashboard
Combine Mindbody's sales API data with internal financial records in a Retool revenue dashboard. Query Mindbody for sales transactions by date range, categorized by product type (class packages, memberships, retail), and display revenue totals alongside month-over-month trends in Retool Charts. Finance managers use this for weekly revenue reviews and monthly reporting to ownership.
Create a revenue dashboard with a month picker and service type filter. Query Mindbody's /sale/sales endpoint for transactions in the selected period. Use a JavaScript transformer to aggregate sales by category (memberships, class packs, retail, services). Show a bar chart of revenue by category and a Stat component for total revenue. Below, display the full transaction table with date, client name, service description, and amount.
Copy this prompt to try it in Retool
Troubleshooting
API requests return 401 Unauthorized even with the Api-Key and SiteId headers configured
Cause: The Api-Key header value is incorrect or the API key has been revoked, or the SiteId value does not match the site associated with the API key. Mindbody's API key is tied to a specific developer account and must be used with the correct SiteId.
Solution: Verify the Api-Key is copied correctly from the Mindbody developer portal with no leading or trailing spaces. Confirm the SiteId matches your business's numeric site ID (not the site name). For sandbox testing, use SiteId: -99 with a sandbox-authorized API key. Check the Mindbody developer portal to confirm the API key is active and not expired.
Class or client queries return 'This endpoint requires a Staff user token' or similar 403 error
Cause: The endpoint being called requires a UserToken (staff authentication) in addition to the API key. Not all Mindbody endpoints are accessible with just the API key — protected data requires a UserToken obtained by authenticating as a staff user.
Solution: Create a Retool query that calls POST /usertoken/issue with the staff user's credentials: include the Api-Key and SiteId headers plus a JSON body with Username, Password, and SiteIds array. Extract the AccessToken from the response and store it in a Retool state variable. Add an Authorization header with the AccessToken value to any query that returns a 403 error.
1// Query body for POST /usertoken/issue to get UserToken2{3 "Username": "{{ retoolContext.configVars.MINDBODY_STAFF_USERNAME }}",4 "Password": "{{ retoolContext.configVars.MINDBODY_STAFF_PASSWORD }}",5 "SiteIds": [{{ retoolContext.configVars.MINDBODY_SITE_ID }}]6}Class schedule query returns an empty Classes array even though classes are scheduled in Mindbody
Cause: The date range parameters are formatted incorrectly — Mindbody's API expects ISO 8601 datetime strings (YYYY-MM-DDTHH:MM:SS format). Dates without the time component or in other formats may cause the API to return empty results rather than an error.
Solution: Ensure StartDateTime and EndDateTime parameters include the full datetime format: '2024-03-01T00:00:00' and '2024-03-07T23:59:59'. Check that the date picker component is returning dates in the correct format. Use a JavaScript expression to format the dates: {{ new Date(dateRangePicker.startDate).toISOString().replace('.000Z', '') }} to ensure proper ISO format.
1// Format date picker values for Mindbody API parameters2// StartDateTime3new Date(dateRangePicker.startDate).toISOString().split('.')[0]4// EndDateTime 5new Date(dateRangePicker.endDate).toISOString().split('.')[0].replace('T00:00:00', 'T23:59:59')Sales query returns only the first 100 transactions even with Limit set higher
Cause: The Mindbody API enforces a maximum Limit value of 100 per request for most endpoints. Requests with Limit values above 100 are capped at 100 results.
Solution: Implement pagination using the Limit (max 100) and Offset parameters together. For full date range exports, create a Retool Workflow that iterates through pages: start with Offset=0, check the TotalResults field in the response, calculate the number of pages needed, and fetch each page in sequence, accumulating results. For dashboard use, 100 transactions per page is typically sufficient with a date range narrow enough to fit within that limit.
Best practices
- Store all Mindbody credentials (API key, SiteId, staff username, staff password) in Retool Configuration Variables marked as secret — never hardcode them in query bodies or resource headers.
- Request a UserToken on page load using a dedicated initialization query, store it in a state variable, and reference it in Authorization headers for all queries that require staff authentication.
- Use Mindbody's sandbox environment (SiteId: -99) for all development and testing — it provides a realistic data set without the risk of creating test bookings or modifying live client records.
- Implement pagination for client and sales queries using the Limit and Offset parameters — large studios with thousands of clients will hit timeouts if you try to fetch all records in a single request.
- Cache class schedule data for 5-10 minutes using Retool's query caching feature — class schedules don't change minute-to-minute and caching reduces Mindbody API calls during busy periods when multiple staff are using the dashboard simultaneously.
- Add 'Only run when' conditions to queries that depend on a selected row or search input — for example, the client detail query should only run when a client is selected, not on every page load.
- Build separate Retool resources for the Mindbody sandbox and production environments and use Retool's environment switching feature to keep test and production configurations separate.
Alternatives
Choose Calendly if you need simple one-on-one or small-group appointment scheduling rather than class-based fitness studio management, as Calendly's API is simpler and requires only an access token without the site-specific auth complexity of Mindbody.
Choose Acuity Scheduling if your wellness business focuses on individual appointments (personal training, massage, therapy) rather than group classes, as Acuity's API provides appointment-centric management with simpler authentication.
Choose Zocdoc if your business is in healthcare or medical wellness and needs patient appointment booking integrated with insurance verification, as Zocdoc's platform is purpose-built for healthcare scheduling workflows.
Frequently asked questions
Do I need a special Mindbody subscription to access the Public API?
Yes — Mindbody's Public API is not available on all subscription tiers. API access is typically included in higher-tier plans or available as an add-on. Contact Mindbody's support team or your account manager to confirm whether your current plan includes API access and to register your application in the developer portal. API keys are issued after application review and approval.
What is the difference between the API key and the UserToken in Mindbody's authentication?
The API key is a static credential that identifies your application and is required for every API request via the Api-Key header. It gives you access to public and lightly-protected endpoints. The UserToken is a session-based credential that represents a specific authenticated staff user — it is obtained by calling /usertoken/issue with a staff account's credentials and used in the Authorization header for endpoints that require staff-level permissions (such as viewing client personal data or processing sales). Many read-only schedule endpoints work with just the API key, but client and sales data typically require a UserToken.
Can Retool create new bookings in Mindbody through the API?
Yes — the Mindbody API includes endpoints for adding class bookings (/class/addbooking) and creating appointments. These POST endpoints require a UserToken with appropriate staff permissions. Build Retool Form components that collect the required fields (ClientId, ClassId, booking date), then trigger a POST query to the booking endpoint on form submit. Always add a confirmation modal before creating bookings to prevent accidental registrations, and test extensively in the sandbox environment before enabling booking creation in production.
How do I get a client's visit history to calculate their total visits and last visit date?
Client visit history is available through the /client/clientvisits endpoint, which accepts a ClientId and date range. Query this endpoint for each client you need visit data for. For dashboard use, avoid calling this per-client in a loop — instead, use a JavaScript transformer to batch client IDs and trigger parallel Retool queries using Promise.all(), or use a Retool Workflow to pre-aggregate visit data into a Retool Database table that the dashboard reads from.
Does Mindbody's API support webhooks for real-time event notifications?
Mindbody offers a webhook system called Mindbody Webhooks for certain business plans, which can send event notifications for bookings, cancellations, and client changes to a configured endpoint URL. However, Retool cannot directly receive incoming webhooks — webhooks require a public HTTPS endpoint that can process incoming POST requests. To use Mindbody webhooks with Retool, set up a separate webhook receiver (a simple cloud function or server-side endpoint) that stores events in a database, which your Retool app then queries.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation