Privacy Policy
Last updated: August 7, 2026
LemurKey.app is a free Morse code receiving practice app for ham radio operators and learners. I operate it at lemurkey.app. This policy describes what information the app collects, how I use it, and the choices you have.
Summary
- The app works fully on your device without an account.
- Creating an account is optional and enables cloud save sync.
- Live DX loads public band data; you may optionally save a station profile (callsign, grid, and related fields).
- Location is optional — only when you tap Use my location or search for a city (Live DX or Account).
- I do not sell your data or show advertising.
- You can delete your account and cloud data from Account → Delete account.
App Store privacy summary
This section maps to Apple’s App Privacy categories for the iOS app and the web app at lemurkey.app. Nothing below is sold or used for advertising.
Location (optional)
If you tap Use my location in Live DX (web or iOS), the app reads your device’s coordinates once to suggest a Maidenhead grid square. Coordinates are processed on your device and are not sent to my servers. If you search for a city name instead, your search text is sent to Open-Meteo Geocoding to resolve city → coordinates; only the query string and standard request metadata go to Open-Meteo. You can always type a grid square manually and never use location features.
User content (optional)
Content you choose to enter or generate in the app, stored locally and (when signed in) in cloud save:
- Practice settings and progress (speed, mode, watts, station unlocks, Koch/Learn state).
- Optional station profile (Live DX and, when signed in, Account): callsign, grid square, QTH, timezone preference, distance units, home bands, satellite tracking, and alert settings. Latitude and longitude are derived from your grid on your device — not typed in separately. A generated callsign avatar is rendered locally from your callsign; no profile photo is uploaded.
- Account username and optional recovery email (see Account below).
- Practice copy you type during rounds stays on your device; it is not uploaded for analytics.
Identifiers
- Supabase user ID — assigned when you create an account; used for cloud save, optional push subscriptions, and analytics when signed in.
- Analytics session ID — a random ID in local storage, used to group events in a visit; not linked to your username in analytics payloads.
- Web Push endpoint and keys — only if you enable streak reminders while signed in (browser/PWA). iOS ISS pass alerts do not create a push token.
Usage data
On production hosts (lemurkey.app and the iOS app), the app may send lightweight
product analytics to my Supabase database — for example app open, mode
changes, round results, and account actions. Each event includes an event name, small
properties (e.g. mode, WPM), a session ID, and your user ID only when signed in. I do
not include your username, recovery email, practice text, callsign, or grid in analytics
events. Local development on localhost is never counted. Contact
privacy@lemurkey.app to request exclusion.
Third-party APIs and services
The app contacts these services when you use related features:
- Supabase — authentication, cloud save, analytics storage, and optional Web Push subscription rows. Privacy policy.
-
Cloudflare — hosts lemurkey.app and runs the Live DX feed worker
(
/v1/feed,/v1/tle) that aggregates public ham-radio sources. Privacy policy. - Open-Meteo — city → coordinates for optional grid lookup in Live DX (no API key; search text only). Privacy policy.
- CelesTrak / AMSAT keps — satellite TLE data when Live DX loads pass predictions (public orbital elements; your grid is used only on-device for pass math).
- Public ham-radio sources (via my feed worker) — NOAA SWPC (space weather), Reverse Beacon Network (CW spots), POTA, and SOTA activations. The worker fetches these on a schedule; your browser or the iOS app then downloads the combined JSON feed. I do not send your username, recovery email, or device location to those upstream services.
Information I collect
On your device (local storage)
Whether or not you sign in, the app stores practice progress in local storage on your device (browser or iOS app), including settings (speed, tone, mode), watts balance, station unlocks, Koch / Learn progress, practice and copy streaks, tour and hint flags, and similar game state. This data stays on your device unless you sign in and sync, or you clear site data (web) or uninstall the app (iOS).
The web app also installs a service worker so core files load offline. The service worker caches static assets on your device; it does not read your practice text or passwords. The iOS app bundles the same files inside the app package and does not use a service worker.
Live DX and station profile (optional)
If you choose Live DX in the top-level navigation, the app stores a local station profile in local storage. Signed-in users can also save the same profile to cloud sync from Account → Station profile, including:
- An optional callsign and grid square (Maidenhead locator — used worldwide).
- Optional QTH, timezone preference, and distance units.
- Optional device location override for Live DX RF math (browser or iOS permission when enabled; home grid remains stored).
- Preferred home bands, active tab, tracked satellites, and alert settings.
- Cached feed and TLE data so Live DX can show recent results offline.
When Live DX loads fresh data, the app requests my public feed at
lemurkey.app/v1/feed (and optionally /v1/tle for satellite
elements). These endpoints return the same aggregated band data for all users; filtering
by your callsign, grid, and bands happens on your device. I do not log
or store your Live DX profile on the feed server.
Grid square helpers (Live DX Home and Account station profile): you can type a grid manually, search by city (query sent to Open-Meteo), or tap Use my location (browser or iOS location permission). Location coordinates are converted to a grid locally and are not uploaded to my servers.
The feed combines public ham-radio sources (NOAA SWPC, Reverse Beacon Network, POTA, SOTA). Satellite passes may also load TLEs from my worker, bundled seed data, or directly from CelesTrak/AMSAT when needed.
If you enable ISS pass alerts in Live DX, the app schedules a local notification on your device before the next ISS pass at your home grid. On the web app this uses the browser notification permission and service worker. On the iOS app it uses on-device local notifications (not remote push; no push token is sent to my servers). You can turn alerts off in Live DX → Home. The schedule stays on your device.
Account and cloud save (optional)
If you create an account, I store:
- A username (3–24 characters, lowercase letters, numbers, underscore).
- A password (hashed by Supabase Auth — I never store plain text).
- An optional recovery email, used only to send a password-reset link if you forget your password. It is not used for marketing. You can add or change it when signed in under Account, or provide one when you create an account.
- A cloud save copy of your synced progress (watts, settings, station unlocks, Koch progress, activity/streaks, station profile when present, and related flags).
If you use Forgot password?, enter your username. When a recovery email is on file, I send a reset link to that address through my auth provider. I do not reveal whether a username exists beyond a generic success message.
Accounts without a recovery email use a synthetic internal address
(@ditdit.invalid or legacy @cwstream.invalid) that is never
emailed and is not shown in the app.
Cloud save is hosted on Supabase (database and authentication). Supabase processes sign-in credentials and stores your save row. See Supabase’s privacy policy.
Streak reminders (optional, signed in)
If you enable Streak reminder in Settings (requires a signed-in account and a configured push key), the app registers a Web Push subscription with your browser and stores it in Supabase, including:
- The push endpoint and encryption keys from your browser.
- Your timezone and a fixed local reminder hour (7 PM).
- Your user ID to associate the subscription with your account.
I use this only to send a daily practice-streak reminder. You can turn it off in Settings; disabling removes your subscription row from Supabase. Streak reminders are separate from Live DX ISS pass alerts (which are local-only).
Product analytics
See Usage data in the App Store privacy summary above for what is collected and how to request exclusion. Analytics require Supabase to be configured in the app build; events are insert-only and not exposed for public browsing.
What I do not collect
- Payment or billing information (the app is free).
- Background or continuous location tracking — location is used only when you explicitly request it in Live DX.
- Contacts, photos, microphone recordings, or clipboard contents.
- Third-party advertising or social tracking pixels.
- Cookies for tracking — the app relies on local storage, not cross-site cookies.
How I use information
- Run practice modes and remember your progress on this device.
- Show Live DX spots, activations, greyline, and satellite passes for your chosen grid.
- Convert optional location or city search into a grid square on your device.
- Sync progress across devices when you use an account.
- Reset your password when you request it and have a recovery email on file.
- Send optional streak-reminder push notifications you enable.
- Understand aggregate usage to improve the app (analytics).
- Protect cloud save from obviously invalid data (server-side validation on watt balances).
Data retention
- Local storage persists until you clear site data, uninstall the PWA, or delete the iOS app.
- Cloud save and account are kept while your account exists.
- Push subscriptions are removed when you disable streak reminders or delete your account.
- Analytics events may be retained for product analysis; if you delete your account, your user ID on past events is cleared (set to null) rather than deleting every row.
Deleting your account
Signed-in users can delete their account from Account → Delete account. Deletion permanently removes your auth account, cloud save, recovery email, and push subscriptions from Supabase. It does not automatically erase local storage on your device — clear site data in your browser if you want a fresh local profile too.
If you cannot sign in, contact me (see below) and I will delete your account if I can verify ownership.
Children’s privacy
LemurKey is a general-audience ham-radio practice tool and is not directed at children under 13. I do not knowingly collect personal information from children under 13. If you believe a child has created an account, contact me and I will delete it.
Security
Passwords are handled by Supabase Auth. Cloud save rows are protected by row-level security so each user can only access their own data. Account deletion requires your password and runs on my server with elevated privileges — it cannot be triggered by another user.
Changes
I may update this policy from time to time. The “Last updated” date at the top will change when I do. Continued use of the app after changes means you accept the updated policy.
Contact
General questions, bugs, or feedback: support@lemurkey.app
Privacy or account deletion: privacy@lemurkey.app