How BetterBite uses WHOOP data, and why it asks for each scope.
BetterBite is an AI calorie and nutrition tracker for iPhone. The WHOOP integration exists for one purpose: to make a person's daily calorie budget reflect the day they actually had, rather than an activity level they picked once during onboarding.
| Scope | Used for |
|---|---|
read:cycles | Day strain and kilojoules, converted to kcal. This is the figure the calorie budget is calculated from. |
read:recovery | Recovery percentage, resting heart rate and HRV. Shown on the home ring and used to soften advice on low-recovery days. |
read:sleep | Sleep duration and sleep performance, shown on the ring and used in the day's guidance. |
read:workout | Session context, so post-workout advice is timed to a real session rather than guessed from the clock. |
read:profile | The WHOOP user id only, to map webhooks back to the right account. No name or email is stored. |
offline | Refresh tokens. Without it the connection dies at the first token expiry. |
Four in total. The first three run at most once every ten minutes per user; the fourth runs once, at connection.
GET /v2/cycle?limit=1GET /v2/recovery?limit=1GET /v2/activity/sleep?limit=1GET /v2/user/profile/basicBetterBite's calorie target is built on an estimated total daily energy expenditure — body metrics multiplied by an activity level the user chose during onboarding. WHOOP measures that same quantity every day, so where a measurement exists the app stops budgeting against a guess.
Only the expenditure above what the target already assumes is credited, and only a fraction of that. Adding back 100% of an estimated burn would pay twice for the activity already built into the target, and wearables estimate expenditure rather than measure it.
A WHOOP cycle begins at wake rather than at midnight, so expected burn is prorated over the cycle's own window instead of the calendar day.
score_state is honoured: PENDING_SCORE renders as "—", never as a
confident zero.api.prod.whoop.com live in a
Cloudflare Worker. No secret ships inside the iOS binary.ASWebAuthenticationSession. The OAuth state is stored
server-side, is single-use, and is bound to the account, so a callback cannot attach one
person's WHOOP account to another's.base64(HMAC-SHA256(timestamp + raw body, client_secret)), compared without an
early exit.Questions about this integration: trybiteai.com/support.