RunFlex
Privacy Policy
Last updated: 22 September 2026
This Privacy Policy explains what RunFlex ("RunFlex", "we", "us") collects, why we collect it, who we share it with, and the choices you have. RunFlex is a running app that suggests routes near you, tracks your runs, and offers an AI running coach. RunFlex is operated by ROFL Marketing Limited.
We built RunFlex to be lean with your data: no ads inside RunFlex, no third‑party advertising or tracking SDKs in the app, no data brokers, and we never sell your data. The one third‑party SDK in the iPhone app handles purchases only (RevenueCat — see §1 “RunFlex Pro purchases”). Your fitness and location data is used to run the app for you — never for advertising, and never sent to an advertising company.
Our public launch page at runflex.app is the one exception, and it is opt‑in. It offers three tools — Google Analytics, the Meta pixel and Microsoft Clarity — that measure how the page is used and help us advertise RunFlex on Google, Facebook and Instagram. They load only if you accept them on the banner (see §1 “Launch‑site analytics and advertising”). Decline and none of them load at all.
1. What we collect and why
Every category below names the part of the app that actually collects it, so this policy stays honest to how RunFlex is built.
Account identity
When you create an account we store your email address and a securely hashed password. If you sign in with Google or Apple instead, we receive and store the provider's account identifier (sub), your email address, and whether that email is verified — we never receive your Google or Apple password.
Where in the app: the users table (email, hashed password, Google/Apple id); OAuth sign‑in in server/services/oauth-signin.ts (Google scope openid email profile, Apple scope name email).
Precise location
When you ask for a route or track a run, the app uses your device's precise location as the start point (and to follow you during a run). Your coordinates are sent to our server to generate routes and are shared with our mapping provider (Mapbox) for geocoding, directions, and map tiles.
Where in the app: device location via @capacitor/geolocation; route generation endpoints in server/routes.ts; geocoding/directions in server/services/location-service.ts, server/generateCircularRoute.ts, and server/services/route-generator.ts.
GPS run traces
When you record a run on the phone or watch, we store a decimated trace of the path you actually ran (capped at ~500 points) so you can review the run and so your pace can be personalised.
Where in the app: the run_history.tracked_path column (shared/schema.ts), written by run‑completion handlers in server/routes.ts.
Run history and pace
We store each completed run's distance, duration, pace, and whether it was a run or walk, to show your history and personalise future time/distance estimates.
Where in the app: the run_history table; trackRunStarted / trackRunCompleted in server/services/analytics.ts.
Saved routes and preferences
Routes you save, their start/end points and features, and your route preferences (distance range, scenery, surface, distance unit) are stored so you can find them again and so routes fit your taste.
Where in the app: the saved_routes and preferences tables; shared route links in shared_routes.
Home address — only if you add one
Registering a home address is optional. If you add one (Profile → Home), we store its coordinates and a label so you can plan a route simply by saying "run home" instead of typing an address each time. Your home is treated as sensitive: we never display the area immediately around it on any summary, overview, shared, or recap map — the first and last 500 metres of a route are always hidden at the home end, and the exact location is stripped from a shared route link before it leaves our servers, so anyone you share a route with cannot see where you live. Only your own in‑app route planning view shows the full way to your door, because you need it to follow the route. We never send your home address to third parties, and it is deleted when you delete your account.
Where in the app: the home_lat / home_lng / home_label columns on ai_user_profiles; clipping logic in shared/home-privacy.ts; shared‑route stripping in server/routes.ts.
AI coach conversations and profile
Messages you exchange with the AI coach are stored so the conversation has memory. To answer you, the relevant recent messages — along with derived context such as your fitness level, preferred distance/pace, recent run stats, current weather, and the names of nearby places — are sent to OpenAI. We do not send your email, name, or raw coordinates to OpenAI.
Where in the app: the ai_conversations and ai_user_profiles tables; server/services/ai-service.ts (OpenAI gpt-4o-mini).
Integration tokens (Google Calendar, Spotify) — only if you connect them
These integrations are optional. If you connect them, we store OAuth access and refresh tokens so the features keep working:
- Google Calendar — read‑only free/busy access (scope
calendar.freebusy) so the coach can suggest good times to run. We request only busy/free time windows; we do not read your event titles or details. - Spotify — to search tracks, read your saved tracks, and create a private playlist for a route (scopes
playlist-modify-private user-library-read).
Where in the app: tokens stored on ai_user_profiles (google_access_token, spotify_access_token, etc.); server/services/google-calendar-service.ts and server/services/spotify-service.ts.
First‑party analytics (product usage)
We keep a first‑party record of key product events to understand how RunFlex is used and to improve it. These events are stored in our own database only — there is no third‑party analytics service. Each event carries your account id and only the coarse details in brackets below — never your location, a coordinate, the shape of a route, or anything you type. The events we record are:
| Event | When it fires |
|---|---|
app_first_open | You open the app for the first time after installing it (the platform only). Stored without your account id or any device identifier, so it can only ever count installs |
sign_up | You create an account (with UTM source/medium/campaign if present) |
login | You sign in |
app_open | You open or return to the app — at most once a day (the platform only) |
quiz_step | You answer or skip a step of the onboarding questions (which step, and whether you skipped it — never your answer) |
quiz_complete | You finish the onboarding questions (how many you answered — never the answers) |
route_generated | A route set is generated (route mode, target distance/duration, how many routes) |
search_scored | A route search is answered: what kind of search it was (for example "trail loop"), whether the routes shown matched it, how many did, and which checks the first route missed — never where you searched or the details of what you asked for |
route_saved | You save a route (distance, feature tags) |
run_started | You start a run |
run_completed | You finish a run (distance, duration, pace, source) |
paywall_view / paywall_dismiss | You see or close the RunFlex Pro screen (where it appeared, and which feature led to it) |
purchase_start | You tap to subscribe (monthly or annual) or to buy lifetime |
trial_start / subscription_active / subscription_churned | Once subscriptions launch: your free trial starts, a paid period begins or renews, or a subscription ends (the store and product only — never payment details, which we never receive) |
Until 11 September 2026, route_generated also recorded the start coordinates of the routes you asked for. It no longer does, and we have deleted those coordinates from every event already stored.
Where in the app: server/services/analytics.ts writing to the analytics_events table; the app sends the install, app‑open, onboarding and subscription‑screen events to POST /api/analytics/event, which rejects any detail not listed above. The full catalogue is docs/runbooks/analytics-events.md.
The launch list (only if you join it)
If you put your address into the form on runflex.app, we store your email address, the country and city you chose, the time you ticked the consent box, and the exact wording that was beside it. The country and city exist for one stated purpose: deciding which cities get verified street‑lighting and map coverage next. We keep the consent wording so that, if the copy is ever reworded, our record still shows what you agreed to.
We use the address to email you about the RunFlex launch and what we're building, and nothing else. It is never sold, and never shared with an advertiser. The list is held in our own database and mirrored into Resend, who send the emails on our behalf and provide the tools we use to write them.
Every email carries an unsubscribe link. When you use it, we record the opt‑out in our own database rather than only at Resend, and we keep your row — marked as unsubscribed — instead of deleting it, so that a later signup somewhere can't quietly put you back on a list you have already left. You can also just reply and ask.
Where in the app: the waitlist_signups table; POST /api/waitlist in server/routes.ts; server/services/launch-list.ts and server/webhooks-resend.ts for the Resend mirror.
Launch‑site analytics and advertising (runflex.app only, with your consent)
Our pre‑launch landing page — and only that page, not the app — can load three third‑party tools, so we can tell which parts of the page work and so we can advertise RunFlex to people likely to want it:
| Tool | What it does |
|---|---|
| Google Analytics 4 | Counts page views and a handful of events: which call‑to‑action you clicked, whether the launch‑list signup succeeded or failed, and clicks out to Instagram. Google advertising signals and ad personalisation are on, which means Google may add your visit to a remarketing audience and report your age range, gender and interest categories to us in aggregate. |
| Meta pixel | Reports the same page view, and a launch‑list signup as a conversion, so we can tell whether an Instagram or Facebook post brought anyone — and so we can show RunFlex ads to people who visited but did not sign up. It also reads the signup form directly (see automatic advanced matching below) and sends hashed contact details it finds there. |
| Microsoft Clarity | Records how the page was used — scrolls, clicks and a replay of the session — so we can see where the page confuses people. Not used for advertising. |
These are non‑essential cookies and similar technologies. None of them load until you accept them on the banner shown on your first visit. If you decline, or if your browser sends a Global Privacy Control or Do Not Track signal, no script is fetched, no cookie is set, and no request reaches any of the three. You can change your mind at any time using the Cookies link in the page footer; a later decline stops the tools loading on your next page load and deletes the identifiers described below.
What is sent about you. Simply reading the page sends no email address, no name and no free‑text — a click is reported as the fact that it happened. All three tools do receive your IP address and browser details, as any web request does, and set their own cookies to recognise a returning browser.
If you join the launch list, we additionally send Meta and Clarity a one‑way SHA‑256 hash of your email address, and Meta a hash of the city and country you chose. The plain values never leave the page. Meta uses this to match the signup to a Facebook or Instagram account (they call it "advanced matching") so the conversion is attributed and so we can build advertising audiences; Clarity uses it only to file the session replay against the signup. Your browser keeps those hashes so a later visit can still be matched, and declining on the Cookies link erases them.
If you type into the form without submitting it, the Meta pixel may still send a hashed copy of what you typed. Meta's pixel has a feature called automatic advanced matching, which we have enabled: rather than being handed specific fields by us, the pixel itself looks at the form on the page and, when you interact with it, sends one‑way hashes of the contact details it recognises. Today that form asks for an email address, a country and a city, so those are what there is to find — but the detection is Meta's, not ours, and it applies to whatever fields the page carries at the time. As above, it is hashed in your browser and only ever happens after you have accepted the banner.
If you would rather not be identified to Meta at all, decline the banner (or send Global Privacy Control, which we honour automatically) — the pixel is then never loaded and has no form to read.
Some of this is sent by our server, not your browser. Many people run an ad blocker, which stops these tools loading at all — so when you join the launch list, our server also reports that one conversion directly to Meta, and to Google if their script did not load. It sends the same hashed email, city and country described above, plus your IP address and browser user‑agent string, which those vendors use to match the event. This happens only if you accepted the banner. If you declined, or your browser sent Global Privacy Control, nothing is reported from the server either — an ad blocker is a technical measure and your answer on the banner is an instruction, and we treat the instruction as the one that decides.
Where in the app: server/services/conversions.ts, called from the launch‑list endpoint in server/routes.ts.
We never send these tools anything about your runs, routes, location or health data. There is nothing to send: the launch page has none of it.
Where in the app: marketing/analytics.js (the consent gate, the tags and the hashing), server/analytics-config.ts (which tools are switched on). Nothing here runs in the RunFlex app itself.
RunFlex Pro purchases (only if you buy or restore one)
RunFlex Pro is sold through Apple's App Store. Apple takes the payment; we never see your card, bank or billing details, and neither does RevenueCat.
To know whether your account has Pro, we use RevenueCat, a subscription service that checks App Store purchases on our behalf. The RunFlex iPhone app includes RevenueCat's SDK, which sends RevenueCat:
- your RunFlex account number, so a purchase is linked to your account and not to a device (never your name or email address);
- your App Store purchase records from Apple: which product (monthly, annual or Founding Lifetime), when it was bought, renewed, cancelled, refunded or expired, whether it is in a free trial, the storefront country and price, and Apple's transaction identifiers;
- basic device and app details (device model, iOS and app version, IP address), as any network request does.
RevenueCat sends us back the same purchase events, and we store on your account whether you have Pro, which product, when the current period ends, and whether you have had a free trial (so the app never offers you a second one — Apple allows one per Apple ID). We also count how many routes your account generates each day, which is how the free route and Pro's fair‑use limits work. We use this only to give you what you paid for. It is never used for advertising.
Where in the app: client/src/lib/purchases.ts (the SDK), server/services/pro-webhook.ts and server/webhooks-revenuecat.ts (what we store), pro_subscriptions, revenuecat_events and route_generation_meter (the tables).
Technical and device data
Like any web service, our servers and the third parties that serve map tiles and fonts to your device receive your IP address as part of normal network requests. We keep basic server request logs for reliability and abuse prevention.
2. How your data is shared (service providers)
RunFlex relies on a small set of vendors to function. We share only what each one needs, for the purpose listed. We do not sell your data, and none of these vendors are advertising or data‑broker services.
| Vendor | What it receives | Purpose |
|---|---|---|
| Mapbox | Coordinates, place‑name/address queries, route waypoints; map tiles load directly in your browser (your IP + map viewport) | Maps, geocoding, directions, elevation |
| OpenAI | Your AI coach messages plus derived context (fitness/preferences, recent run stats, weather, nearby place names) | AI running coach replies |
| OpenWeatherMap | Your coordinates | Current weather and forecast for a run |
| Resend | Your email address; and if you joined the launch list, your address is also stored there as a contact | Sending the password‑reset email; storing and mailing the launch list |
| Google (Calendar API) | Free/busy time windows; your Google id + email at sign‑in | Optional calendar suggestions; Google sign‑in |
| Spotify | Track search queries, saved‑track reads, playlist writes | Optional route playlists |
| OpenStreetMap / Overpass | Geographic area queries only — no personal data | Finding parks, water, trails, lighting near a route |
| Google Fonts / Cloudflare (Font Awesome) | Your IP (static asset requests) | Fonts and icons |
| Google (Analytics 4) | Launch page only, and only if you accept: your IP, browser/device details, pages viewed and the events listed above. If their script is blocked by your browser, a completed signup is sent from our server instead | Measuring which parts of the launch page work, and remarketing audiences for RunFlex ads |
| Meta (Facebook pixel + Conversions API) | Launch page only, and only if you accept: your IP, browser/device details, page view and launch‑list signup, plus hashes of the contact details you enter in the signup form — the email, city and country we send on a completed signup, and any the pixel detects itself if you fill the form in without submitting. A completed signup is also sent from our server, with the same hashes plus your IP and user‑agent | Measuring whether our social posts bring signups, and showing RunFlex ads to people who visited |
| Microsoft (Clarity) | Launch page only, and only if you accept: your IP, browser/device details, a recording of your session on that page, and a hash of your email if you join the list | Seeing where the launch page confuses people. Not used for advertising |
| RevenueCat | Your RunFlex account number, your App Store purchase records (product, dates, trial, storefront, price, Apple transaction ids), and device/app details — iPhone app only, and only for purchases. Never payment details, your name or your email | Checking App Store purchases and telling us whether your account has RunFlex Pro |
| Apple (App Store) | Your purchase and payment, which Apple handles under its own privacy policy — we never receive payment details | Selling RunFlex Pro |
| Neon (database) & Railway (hosting) | All stored account data, on our behalf | Running and storing the app |
Where in the app: server/services/weather-service.ts, server/email.ts, server/services/overpass-client.ts, client/index.html (fonts/icons/Mapbox CSS), server/db.ts and Procfile (hosting).
We may also disclose data if required by law, to enforce our Terms, or to protect the rights and safety of our users.
3. Health and fitness data
Your runs, pace, and GPS traces are fitness data. We treat them as sensitive: we never use your health or fitness data for advertising or marketing, and we never share or sell it to data brokers or advertising networks. It is used only to provide the app's features to you (showing your history, personalising pace and route suggestions).
4. What we do not do
- No ads in RunFlex. The app and the launch page show no advertising. We do advertise RunFlex elsewhere, on Google, Facebook and Instagram, and if you accepted the launch page's banner your visit can be used to target those ads — see §1. That is the only advertising use we make of anything.
- No third‑party tracking in the app. The RunFlex app contains no advertising or analytics SDKs, no tracking pixels and no session‑replay tools. Its one third‑party SDK is RevenueCat's, which handles purchases and nothing else, and receives none of your runs, routes or location. Its only analytics are the first‑party events above, stored in our own database. The three tools on the public launch page are the sole exception, they are opt‑in, and they never see your runs, routes or location.
- Never your fitness or location data. Nothing you do in the app — runs, routes, coordinates, health data — is ever sent to an advertising or analytics company. The launch page has none of it to send.
- No sale of data. We do not sell or rent your personal information. Some US state privacy laws treat advertising tools like the ones on the launch page as a "sale" or "sharing" of personal information; if that is your law, declining the banner — or sending Global Privacy Control, which we honour automatically — is your opt‑out, and nothing loads at all.
5. Data retention
We keep your account data for as long as your account exists. When you delete your account (see below), your personal data is erased. Product analytics events are de‑identified at deletion — the link to your account (user_id) is removed — and only anonymous aggregate counts are retained. We may keep limited records where required by law.
6. Deleting your account and data
You can delete your account and all associated data at any time, directly in the app:
- Open Profile.
- Scroll to Danger zone and tap Delete account.
- Type DELETE to confirm.
When you confirm, we:
- attempt to revoke any connected Google and Spotify OAuth grants;
- permanently delete your saved routes, shared‑route links, run history (including GPS traces), preferences, any saved home address, AI conversations, AI profile, and password‑reset tokens;
- delete your RunFlex Pro record and your route counts, and unlink your account from our record of App Store purchase events (the sale itself is kept, without your account, for our accounts and the Founding Lifetime limit);
- de‑identify your analytics events (unlink them from your account); and
- end all of your active sessions on every device.
Where in the app: DELETE /api/account in server/routes.ts → storage.deleteAccount in server/storage.ts.
Deleting your account does not cancel a RunFlex Pro subscription. Apple bills it, so cancel it in iPhone Settings → your name → Subscriptions. Apple and RevenueCat keep their own purchase records under their own policies; contact us and we will ask RevenueCat to delete the record linked to your account number.
If you cannot access the app, email us at the address below and we will delete your account on request.
7. Your rights
Depending on where you live, you may have rights to access, correct, export, or delete your personal data, and to object to or restrict certain processing. You can exercise most of these in‑app (edit your profile, delete your account) or by contacting us. We will respond within the time required by applicable law.
Where we rely on your consent — the launch‑site analytics above — you can withdraw it as easily as you gave it, using the Cookies link in the footer of runflex.app. Withdrawing consent does not affect anything done before you withdrew it.
8. Children
RunFlex is not directed to children under 13, and we do not knowingly collect personal data from them. If you believe a child has provided us data, contact us and we will delete it.
9. International users
RunFlex and its service providers are operated primarily in the United States. If you use RunFlex from outside the United States, your data may be processed in the United States and other countries where our providers operate.
10. Changes to this policy
We may update this policy from time to time. When we do, we will change the "Last updated" date above and, for significant changes, provide a more prominent notice in the app.
11. Contact us
Questions or requests about your privacy? Email privacy@runflex.app
Governing law and jurisdiction: This Agreement is governed by the laws of England and Wales. The courts of England and Wales have exclusive jurisdiction to settle any disputes.