mobieusKnow Handling Apple Health and Health Connect permission tickets History #503
Author
Patrick Bass
Submitted
Aug 22, 2026 5:34pm
Summary
Workouts: sync troubleshooting, health-platform permissions, and coach access
No body changes between this revision and the current version.

Health platform permissions are the single most common source of "it is not syncing" tickets, and almost none of them are bugs. This is how to tell.

== The first question is always which platform ==

Apple Health (iOS) and Health Connect (Android) are different systems with different failure modes. Do not give an iOS answer to an Android ticket.

== Apple Health ==

Loopa '''reads''' weight, body fat, waist, blood pressure, heart rate, resting heart rate, blood glucose, steps, exercise minutes, water, sleep and workouts. It '''writes''' weight, body fat, waist, blood pressure, resting heart rate, blood glucose, water and workouts.

Sleep is read-only on purpose. Loopa does not author sleep data and asking to write it would be requesting a scope we do not use, which App Store Guideline 5.1.3 does not allow.

'''The most common cause of "nothing syncs":''' iOS permissions are per-type and per-direction, and the member granted some and not others. Apple does not tell the app which ones were refused - by design, so an app cannot infer what you are hiding. That means Loopa genuinely cannot display "you denied weight".

Send them to: '''Settings, then Privacy and Security, then Health, then Loopa'''. Everything they want synced has to be on there. Turning a category on in Loopa's own screen does nothing if iOS is refusing it.

'''"I connected but my old workouts did not come in."''' Connecting starts the sync from that point. Bringing history across is a separate action - Easy Switch, under More - and it reads the full export rather than the live stream.

== Health Connect ==

Loopa reads steps, weight, hydration, exercise sessions, resting heart rate, blood pressure, body fat, sleep, blood glucose, oxygen saturation and body temperature. It writes weight, hydration and exercise sessions.

'''Health Connect must be installed and set up.''' On Android 13 and earlier it is a separate app from the Play Store. On Android 14 and later it is part of the system. A member on an older device who has never opened it will see nothing sync and no error, because there is nothing to talk to.

'''"Connected" means at least one read permission was granted, not all of them.''' A member can be connected and still be missing the one category they are asking about. Send them to Health Connect, then App permissions, then Loopa.

'''Loopa filters out its own writes.''' A session Loopa wrote to Health Connect is ignored when reading back, matched on the writing package. That is what stops an echo loop, and it is why a workout logged in Loopa does not appear twice.

'''Heart rate is not read.''' It was deliberately removed. If a member asks why their heart rate is not in Loopa on Android, the answer is that Loopa does not request raw heart-rate samples - not that something is broken. Do not raise this as a bug.

== "It worked and then stopped" ==

Both platforms can revoke silently after an OS update or a restore from backup. The fix is the same on both: open the platform's own settings, confirm Loopa is still permitted, and if it is, disconnect and reconnect inside Loopa.

Check what the server has seen:

SELECT sync_type, last_push_at, last_pull_at, pushed_count, pulled_count, last_error, client_auth_state FROM health_sync_state WHERE user_id = ?;

client_auth_state is what the app last reported about its own permissions. denied or notRequested against the type they are asking about is your answer, and it is a device-side fix, not a server one.

== What to escalate ==

A ticket is worth engineering time when the platform says permission is granted, the member has waited through a sync, and health_sync_state shows either no row for that type or a last_error. Everything else is a permissions conversation.

Health platform permissions are the single most common source of "it is not
syncing" tickets, and almost none of them are bugs. This is how to tell.

== The first question is always which platform ==

Apple Health (iOS) and Health Connect (Android) are different systems with
different failure modes. Do not give an iOS answer to an Android ticket.

== Apple Health ==

Loopa '''reads''' weight, body fat, waist, blood pressure, heart rate, resting heart
rate, blood glucose, steps, exercise minutes, water, sleep and workouts. It
'''writes''' weight, body fat, waist, blood pressure, resting heart rate, blood
glucose, water and workouts.

Sleep is read-only on purpose. Loopa does not author sleep data and asking to write
it would be requesting a scope we do not use, which App Store Guideline 5.1.3 does
not allow.

'''The most common cause of "nothing syncs":''' iOS permissions are per-type and
per-direction, and the member granted some and not others. Apple does not tell the
app which ones were refused - by design, so an app cannot infer what you are hiding.
That means Loopa genuinely cannot display "you denied weight".

Send them to: '''Settings, then Privacy and Security, then Health, then Loopa'''.
Everything they want synced has to be on there. Turning a category on in Loopa's own
screen does nothing if iOS is refusing it.

'''"I connected but my old workouts did not come in."''' Connecting starts the sync
from that point. Bringing history across is a separate action - Easy Switch, under
More - and it reads the full export rather than the live stream.

== Health Connect ==

Loopa reads steps, weight, hydration, exercise sessions, resting heart rate, blood
pressure, body fat, sleep, blood glucose, oxygen saturation and body temperature. It
writes weight, hydration and exercise sessions.

'''Health Connect must be installed and set up.''' On Android 13 and earlier it is a
separate app from the Play Store. On Android 14 and later it is part of the system.
A member on an older device who has never opened it will see nothing sync and no
error, because there is nothing to talk to.

'''"Connected" means at least one read permission was granted, not all of them.''' A
member can be connected and still be missing the one category they are asking about.
Send them to Health Connect, then App permissions, then Loopa.

'''Loopa filters out its own writes.''' A session Loopa wrote to Health Connect is
ignored when reading back, matched on the writing package. That is what stops an
echo loop, and it is why a workout logged in Loopa does not appear twice.

'''Heart rate is not read.''' It was deliberately removed. If a member asks why their
heart rate is not in Loopa on Android, the answer is that Loopa does not request raw
heart-rate samples - not that something is broken. Do not raise this as a bug.

== "It worked and then stopped" ==

Both platforms can revoke silently after an OS update or a restore from backup.
The fix is the same on both: open the platform's own settings, confirm Loopa is
still permitted, and if it is, disconnect and reconnect inside Loopa.

Check what the server has seen:

<syntaxhighlight lang="sql">
SELECT sync_type, last_push_at, last_pull_at, pushed_count, pulled_count,
       last_error, client_auth_state
  FROM health_sync_state WHERE user_id = ?;
</syntaxhighlight>

<code>client_auth_state</code> is what the app last reported about its own
permissions. <code>denied</code> or <code>notRequested</code> against the type they
are asking about is your answer, and it is a device-side fix, not a server one.

== What to escalate ==

A ticket is worth engineering time when the platform says permission is granted, the
member has waited through a sync, and <code>health_sync_state</code> shows either no
row for that type or a <code>last_error</code>. Everything else is a permissions
conversation.