Lepo · iPhone and Apple Watch

Privacy

Lepo never sends your health data on its own. It sends usage analytics, and this page lists everything they contain. The one thing that can carry health readings off your device is a diagnostics report, and only you can send it.

Health data

Lepo reads from Apple Health and never writes to it. The app requests read-only access, so it has no ability to add, change, or delete anything in Health.

Your readiness score, sleep figures, heart rate, and every other measurement are computed and kept on your device. They live in a container shared between the app, the watch app, and the widgets, so all three can show the same numbers. They stay there, and in your own iCloud or device backups if you have those switched on.

No health reading of any kind is transmitted off the device by the analytics below. Not a score, not a sleep duration, not a heart rate, not a single measurement. This was checked by listing every property the analytics service has actually received.

That covers everything Lepo sends on its own. There is one thing you can choose to send, and it is different. Settings has a Send Feedback + Report button that writes a diagnostics report. If your iPhone has a mail account set up, it opens your mail app with the report attached, addressed to support. Alongside debug logs, that report holds your baseline averages for resting heart rate, HRV, respiratory rate, and maximum heart rate: the rolling average, the spread, how many days it is built from, and how confident it is. Those are health readings. They are in the file because without them a bug report cannot tell a baseline that is still filling up from one where Lepo read nothing at all. Nothing is sent until you press send in your own mail app, and you can read or delete the attachment first.

The share sheet is the other way out, and you can reach it two ways. If your iPhone has no mail account, there is no mail app for Lepo to open, so it shows you the support address and hands the report to the share sheet instead. And underneath the mail button there is an Export Report button that opens the same share sheet straight away, on any iPhone, for when you would rather handle the file yourself. Either way that file is not addressed to anyone, so where it goes is your choice: Messages, AirDrop, Files, or any other app in the sheet. The report stays on your device until you finish sending or saving it in the app you picked, and closing the sheet sends nothing.

Two things sit close enough to that line to name them. When the morning briefing is held back because a resting heart rate or respiratory rate reading has not arrived yet, the app records that it waited, for how many seconds, and whether the score it was waiting on was complete by the time it gave up. On the watch, the app also records which kinds of Health data Apple Health said had changed, how many times each hour, and when it last heard of a change, and, when it was slow to answer a change, which kind it was and exactly when it was told. That can show when a workout or a night's sleep was saved, roughly to the hour and sometimes exactly, but never what it contained. Neither includes a reading, a value or a measurement. Both are listed in the table below with everything else.

Wellness disclaimer

Lepo is not a medical device. Scores and insights are for general wellness and informational purposes only — they are not medical advice, diagnosis, or treatment. Always consult a qualified health professional before making decisions about your health.

Analytics

Lepo sends usage analytics to PostHog, hosted in the European Union at eu.i.posthog.com. PostHog processes this data on Lepo's behalf. Nobody else receives it.

What is sent Why
Install ID, a random UUID generated on your device the first time you open the app. Your paired Apple Watch uses your iPhone's once the two have synced. A watch that has not synced with an iPhone running this version of Lepo uses its own. A synced watch also records its own earlier ID alongside your iPhone's, so the events it sent before the sync can still be found. There is no sign-in, so this is what makes it possible to understand usage per install, and to count your iPhone and your watch as one person rather than two. It is not an Apple ID, an account, or the advertising identifier, and it is not linked to any identity.
Whether the build is debug, TestFlight, or production, and whether the event came from iPhone, iPad, or Watch To keep test builds out of real numbers, and to tell phone behavior apart from watch behavior.
What you did in the app: which screen you were on — home, settings, one of the three metric screens, the paywall, the help screen, or a step of onboarding — which sections of the help screen came on screen, which onboarding step you reached and whether you finished, whether the Health access request completed, notification permission state, which metric tile was tapped, which time range you chose, when you inspected the graph, settings changes such as theme and day count, how many complications are installed and of which kinds, and that you opened a morning or evening notification — along with which stage of the morning schedule it came from and, when the briefing was held back waiting for a resting heart rate or respiratory rate reading to arrive, how many seconds it was held and whether the score it was waiting on was complete by the time it gave up. Tapping Send Feedback + Report or Export Report is recorded too: which button you tapped, whether it opened your mail app or the share sheet, and, if it opened your mail app, whether you then sent the message, saved it as a draft, or cancelled. What you wrote, where you sent the file, and what the report contains are not recorded. When Lepo asks the App Store to show its rating prompt, that is recorded too, along with how many days Lepo had shown you a score by then. Lepo cannot see whether the prompt appeared or what you rated, so neither is recorded. To see which parts of the app get used and where people get stuck. For the feedback button, to know whether a report a person went to the trouble of producing actually got sent. For the rating prompt, to know whether it is ever reached.
Refresh and sync diagnostics: whether a background refresh completed or was skipped and which kind of refresh it was, how long it took and how long each internal stage of it took, how stale the cached data was in minutes, which kind of Health query failed, whether refreshing a score's breakdown wrote it, left it unchanged or failed, and how often its confidence indicator was held back when the watch prepared data for the iPhone and why, how many times a refresh asked each kind of complication to reload and the smallest and largest number of kinds a single refresh asked for, how long a complication took to prepare what it shows and how long the system took to come and ask for it after an update was requested, how a complication drew the small bars under its graph — from the stored per-period values, from a reconstruction of them, or not at all — along with how many of those periods it had and how many hours each one covers, that a complication fell back to showing its empty placeholder instead of the graph, whether the watch accepted or refused the purchase status its paired iPhone handed it and on what grounds, whether the iPhone was able to hand that status over at all and what stopped it if not, that the device or wearable Lepo reads from has stopped writing anything new to Apple Health — roughly how long ago in broad ranges such as one to two weeks, never an exact figure, which of the three scores had nothing to read, and whether looking further back found anything — how many morning notifications appear to have fired, and whether each was the full briefing, one held back for a resting heart rate or respiratory rate reading, or the message that your sleep data had not synced yet; counts of morning and evening notifications found in Notification Center when Lepo next runs; on the watch, which kinds of Health data Apple Health said had changed, or reported an error about (heart rate, heart rate variability, resting heart rate, respiratory rate, sleep or workouts), counted per hour, along with when the watch app last heard of such a change and when the watch app was started, how many times each hour Apple Health woke the watch app with a group of such changes and how the watch app answered each group (after refreshing, without needing to refresh, by joining a refresh already running, or when its time limit ran out), whether a group was still unanswered when the watch app stopped, and, for a change the watch app was slow to answer, which kind of Health data it was about, when the watch app was told of it and how long it took to answer; and error codes and messages. Notification counts are incomplete and do not tell us whether you saw them. Notification text and individual delivery times are not sent. The Health change counts say that something changed and when, never what it was. Widgets and complications go out of date in ways that are invisible from the outside. These events help find and fix those problems and check whether morning and evening notifications are being delivered.
The paywall and purchases: which part of the app opened the paywall, and for a purchase that was started, canceled, completed, or failed — the product identifier, whether it is the monthly, yearly or lifetime plan, the amount charged or the price shown along with its currency, whether a free trial or an introductory offer applied, Apple's identifiers for the subscription and for the individual charge, and whether Apple handled it as a real purchase or a test one. A failure carries the error alongside it. It is also recorded when the plans could not be shown at all — whether that was on opening the paywall or on tapping Try again, and whether the App Store returned an error or simply had nothing to offer. Tapping Restore Purchases is recorded on its own, and so is backing out of it or having it fail. To know which products people buy and what they are worth, to see where the paywall is reached from and where it is abandoned, to find out when someone was shown no plans to choose from, and to find purchases that break.
What happens to a subscription afterwards: that it renewed, lapsed, changed plan, converted from a trial, entered a billing retry or grace period, was switched off or back on for the next renewal, or was refunded — with the amount where money moved, the same two Apple identifiers as above, the date it took effect, the date the app found out, and whether Apple handled it as a real purchase or a test one. Where a subscription stopped renewing, Apple's reason for it: that it was turned off, that a payment failed, that a price rise was not accepted, or that the plan is no longer sold Apple tells the app about a renewal or a lapse only while the app is running, so a subscription that ended with the app closed is a difference found later rather than something seen happening. Without both dates, every ending gets filed to whenever its owner next opened the app. Knowing that a subscription was switched off, and why one ended, is the difference between a plan people stop wanting and a payment that simply failed — the second is worth fixing rather than accepting.
Whether this install currently has Pro, on which plan, whether it is in a trial, and when it first became Pro To read every other number above separately for paying and non-paying installs. This is current state, kept alongside the install identifier rather than sent on every event.
Which of the two Readiness inputs you have turned off in Settings, if any: HRV, resting heart rate, or both. Never the readings themselves, and never why. Readiness built from fewer inputs is less certain, so its numbers are read separately. This is current state, kept alongside the install identifier rather than sent on every event, and nothing is sent if you never use those switches.
Turning analytics off, and turning it back on So that events stopping is distinguishable from an app that crashed or was deleted. Switching off sends one last event saying so, and then nothing further is sent.

Tile names, never tile values. Tapping the sleep tile sends the word "sleep". It does not send how long you slept.

Turning it off

All of this is optional and the switch is in the app, not in an email to me. Open Settings, find the Privacy section, and turn off Share analytics from this device. Nothing further is sent from that device.

Switching it off sends one final event recording that you switched it off, before the sending stops. That is deliberate rather than sneaky: without it, a device going quiet is indistinguishable from a crash, and the crash would get chased instead of respected. It carries the same install identifier as the rest and no health data.

Each device has its own switch. Turning it off on your iPhone does not turn it off on your Apple Watch, or the other way round. That stays true once they have synced: a synced watch files its events under your iPhone's identifier, but the switch on each device still decides whether that device sends anything.

Your iPhone tells your Apple Watch whether you have Lepo Pro. The watch often cannot check a purchase for itself, and without being told it would show the free version to someone who has paid. Your iPhone also hands the watch its install identifier, which is how a synced watch comes to use the same one. Once you have used the Readiness input switches on your iPhone, it hands the watch that setting as well, whichever way the switches stand, so both build Readiness from the same inputs. What crosses is the purchase status, the date a subscription runs until, that identifier, and which Readiness inputs are turned off, nothing more. It goes straight between your own two paired devices over Apple's Watch Connectivity, the same way the app already passes them health figures they both need, and it goes nowhere else: not to a server of mine, not to PostHog, not off the pair at all. The identifier is handed over whether or not your iPhone shares analytics, because handing it over sends nothing to PostHog. Whether the watch then sends its own events under it is up to the watch's own switch.

Purchases go through Apple's App Store. Your card and payment details are handled entirely by Apple and never reach Lepo. What does reach Lepo is the amount a purchase charged and its currency, listed in the table above. Two of Apple's identifiers go with it: one for the subscription and one for the individual charge. They identify the purchase, not you — neither is your Apple Account, and neither can be traced back to a person by Lepo. They are there so that a renewal seen by both your iPhone and your iPad is counted once rather than twice.

What the PostHog SDK adds on its own

iOS redacts the device name to just "iPhone" before the SDK sees it, so if you have given your device a name, that name is not transmitted.

On iPhone and iPad, crashes and unhandled exceptions are reported automatically.

Approximate location

Lepo does not request location access, does not use Core Location, and never sends a location. But events reach PostHog over the network, and PostHog looks up the IP address they arrive from to infer an approximate location on its servers: country, region, city, postal code, and rough coordinates. That inference is attached to events after they leave your device.

The app never learns where you are. What is inferred is roughly where the network you were on is, at city accuracy rather than GPS accuracy. It is real, it is worth telling you about, and it is not location tracking.

What Lepo does not do

Who is responsible for this data

Lepo is made by Tuomas Koponen, an independent developer in Finland, who is the data controller for everything described on this page. There is no company behind it — it is one person.

Reach him at privacy@lepohealth.app.

Why Lepo is allowed to collect it

Health data is not collected at all, so this only concerns the usage and diagnostic data described above.

That data is processed on the basis of legitimate interests: understanding which parts of the app get used, and finding faults that are invisible from the outside — a complication that has quietly stopped refreshing is the usual example. It is not used to profile you, to target advertising, or to make any decision about you.

You can object to it at any time, and you do not have to give a reason. You do not have to ask me either — the switch described under Turning it off above stops it on the spot. See your rights below.

How long it is kept

Analytics events are kept for one year and then deleted automatically. Nothing is kept longer than that, and there is no archive of older events.

Your rights

If you are in the EU or EEA, you can ask for any of the following:

Because there are no accounts, the only handle on your data is the random install identifier described above. Once your iPhone and your Apple Watch have synced, the watch uses your iPhone's identifier. The first time the watch shares analytics after that, it records its own earlier identifier with your iPhone's, and from then on your iPhone's identifier covers both devices, including what the watch sent before they synced. A synced watch that has not shared analytics since, because its switch has been off, shows both identifiers in its Settings, and a request needs both. A watch that has not synced still uses its own, and a request needs that one too, or only part of your data can be found.

You can find it in the app under Settings, in the Privacy section, labeled "This device's ID". On iPhone, tapping it copies it. On Apple Watch it is shown but cannot be copied, because watchOS gives apps no pasteboard. A synced watch shows your iPhone's identifier there and says so. If your watch shows an identifier of its own, read it off the screen and quote it along with your iPhone's.

You can also complain to the data protection authority in your own country.

Contact

Privacy questions, and any of the requests above, go to privacy@lepohealth.app.

Last updated 5 October 2026