Pull your own MAC+ (MACFit / Mars Athletic) workout data and set up a repeatable export. Own-account data only.
- Puller scaffold built (
macplus_puller.py): auth flow + paginated pulls + CSV/JSON output are done. The server-specific bits (base URL, endpoint paths, JSON field names) are markedTODO(capture)and need one round of request capture to fill in. - Endpoint discovery is blocked on your device. It can't be done from a cloud sandbox: no phone, no emulator, no login. See the capture guide below, it takes ~15 min.
Checked whether the API is public so the script could skip capture. It isn't:
portal.macfit.comis a single-page app; its login page ships no readable endpoints, the real calls are in a JS bundle that runs client-side.- No public API docs, OpenAPI/Swagger, or community endpoint maps exist for
com.marsathletic.android.macfit.appor the portal. - App facts confirmed: login is by mobile phone number; profile shows workout stats; there's a QR turnstile check-in and a friends leaderboard. Vendor: MARS SPORTIF.
Conclusion: the fastest path is capturing your own requests once. The script is built so that's a fill-in-the-blanks job, not a rewrite.
Try A first (no phone setup). Fall back to B only if the portal lacks lift/set detail.
- Log into https://portal.macfit.com in Chrome.
- F12 > Network tab > filter Fetch/XHR. Tick "Preserve log".
- Click through profile / history / workouts / check-ins / classes.
- For the login call and one workout-history call: right-click > Copy > Copy as cURL.
- Also note, for each: the request URL, the
Authorizationheader (or cookie), and the JSON response shape (Response tab).
Android emulator is cleanest. Full steps are in the original handoff brief
(macplusextraction.md, Step 3-4): mitmproxy + apk-mitm for cert pinning, or
frida/objection on a rooted emulator, then capture the login and one workout-history call.
- The login request(s): URL, method, headers, body. Both steps if it's OTP (request-OTP then verify-OTP).
- One workout-history request: URL, method, headers, query params, and the JSON response (first page is enough to see the shape and the pagination fields).
- Same for check-ins / classes / activities if you want those exported too.
From that I fill in BASE_URL, AUTH, and ENDPOINTS in the script and it's ready.
cd "Projects/MAC+ Data Extraction"
pip install requests
cp .env.example .env # set MACPLUS_BASE_URL and MACPLUS_PHONE
python3 macplus_puller.py login # OTP prompt or PIN; caches token to .macplus_token.json
python3 macplus_puller.py whoami # sanity check
python3 macplus_puller.py pull # writes export/{workouts,checkins,classes,activities}.{json,csv}
python3 macplus_puller.py pull --only workoutsThe token is cached (chmod 600). Re-run login when it expires (401 tells you).
A 1s delay sits between calls so the private API isn't hammered (MACPLUS_DELAY to tune).
Everything server-specific is in three places at the top of macplus_puller.py:
- CONFIG —
BASE_URL,BASE_HEADERS(copy the app's exact headers here). - AUTH — OTP or PIN flow, field names, and where the token sits in the response JSON.
- ENDPOINTS — one entry per dataset: path, pagination params, and the JSON path to the rows.
Once the one-off export works, the same auth+pull logic drops into an n8n HTTP Request flow or a Remote Cloud Routine (see vault Automation Deploy table) for a recurring export.
- Own account data only.
- Private API may breach ToS: keep the delay, don't hammer it.