Log daily Mindbody sales and class attendance to Sheets
Every night your studio's completed sales and class attendance land in a Google Sheet, so you can track trends without pulling manual reports.
Every night at 11:30pm, log the day's numbers from Mindbody into a Google Sheet so I can track trends without pulling manual reports out of Mindbody by hand. Build this as a scheduled code workflow on a cron trigger. The target window is the current calendar day, from 00:00:00 to 23:59:59 in the site's local time. Because the run itself happens at 11:30pm, also re-process the previous calendar day on every run, so late evening sales and any attendance statuses that were changed after last night's run still get picked up.
Mindbody authentication: every request sends the API-Key and SiteId headers. Get Sales, Get Transactions, and Get Class Visits all return sales, client, and staff specific data, so they additionally require a staff user token. Issue a fresh staff user token at the start of each run and pass it as the raw Authorization header value with no Bearer prefix. Tokens are only valid for 24 hours, so a nightly job must mint its own rather than relying on a cached one.
For sales, call Mindbody Get Sales for the date window. Mindbody list endpoints paginate with Limit and Offset and return a PaginationResponse containing TotalResults, so page through by increasing Offset until Offset plus PageSize is greater than or equal to TotalResults, rather than assuming a single call returns the whole day. A busy studio will have more sales than one page holds. Then call Get Transactions for the same window to pick up payment detail, and group those transactions by their sale ID so each sale row carries the payment method, the transaction status, and the settled amount. Where one sale has several transactions against it, fold them into that single sale row instead of emitting duplicate rows.
For attendance, call Get Classes for the same date window to get every class that actually ran, then for each class returned call Get Class Visits using that class ID. Derive three counts from the visit list rather than just counting roster size. Booked is the number of visits on the class. Attended is the number of visits marked as signed in. No show is the number of visits that were booked, are not marked signed in, and were not late cancelled. No show is the metric studio owners care most about, so late cancels must be excluded from it and reported as their own column when the visit data distinguishes them.
Write to Google Sheets using Append Values, always appending so the history builds up and nothing is overwritten. One row per sale goes to a tab named Sales, and one row per class goes to a tab named Attendance. Every row on both tabs must carry the business date, the location, and the staff member, so the sheet can be pivoted by instructor or by site. The Sales tab should also carry the sale ID, the client ID, the item or service sold, the quantity, the gross amount, the payment method, and the transaction status. The Attendance tab should also carry the class ID, the class name, the class start time, the booked count, the attended count, and the no show count. Use USER_ENTERED as the value input option so dates and numbers land as real dates and numbers and stay pivotable, instead of arriving as text.
The run has to be safe to repeat without duplicating rows for a date that was already logged. Before appending anything, read the existing rows back with Get Values on each tab and build a set of the keys already present. Key the Sales tab on the business date plus the sale ID, and key the Attendance tab on the business date plus the class ID. Filter the rows you are about to write down to only the keys that are not already in the sheet, then append what is left. If a tab has nothing new, skip its append call entirely rather than writing an empty row. This guard is what makes both retries and the previous day re-check safe, so a nightly job that gets retried never double counts revenue.
Mindbody returns monetary amounts as decimal numbers in the site's currency rather than minor units, so write the amounts through as they come back and do not convert from cents. Stay within the Mindbody rate limit of roughly 2000 requests per minute per site while paging through a busy day. If a run fails partway through, the idempotency guard means re-running it simply fills in whatever did not get written the first time.
What does this prompt do?
- Runs every night at 11:30pm and collects the day's completed sales along with how each one was paid.
- Gathers every class that ran that day with its booked count, attended count, and no show count.
- Adds one row per sale to a Sales tab and one row per class to an Attendance tab, always appending so your history builds up over time.
- Stamps every row with the date, location, and staff member so you can pivot by instructor or by site.
What do I need to use this?
- A Mindbody account, plus staff login details that are allowed to view sales and class attendance
- A Google account with the spreadsheet you want the numbers written into
- Two tabs in that spreadsheet, one named Sales and one named Attendance
How can I customize it?
- Change the nightly run time, or run it more than once a day if you want numbers earlier in the evening.
- Point it at a different spreadsheet or rename the tabs it writes to.
- Add, remove, or reorder the columns on each tab, for example splitting revenue into products versus services.
- Narrow it to a single location if you only want one site tracked.
FAQs
Will it double count my revenue if the job runs twice?
Where does the no show number come from?
Does this work if I run more than one location?
Will it overwrite the data already in my spreadsheet?
What happens on a really busy day with hundreds of sales?
Related templates
Every Monday, check every S3 bucket for public exposure, missing encryption and weak backup settings, then get the risks ranked in Slack.
Every weekday at 7am, sign in to the tender portals you track, filter new notices against your bid criteria, and open a deal for the ones worth chasing.
Every weekday at 4pm, spot the threads that went quiet, stage a ready-to-send nudge in your mailbox, and get a ranked Slack recap.
Keep a spreadsheet of your most important senders, and every email from one gets labeled, posted to your team channel, and logged automatically.
The moment an order is fulfilled, we register it with Yotpo so the review request is timed off real delivery, and we log every sync so failures never go unnoticed.
Every night at 11pm we compare the day's Shopify orders with your Zoho Books invoices and payments, and flag only what does not match.
Stop pulling manual reports out of Mindbody.
Let every night's sales and attendance numbers land in a spreadsheet on their own, ready to pivot by instructor or by site.