Privacy Policy
Effective October 6, 2026
Summary
Stacks is a personal workout and nutrition tracker. The data recorded in the app is stored so that the app can display it back. It is never sold, never used for advertising, and never shared with third parties for marketing purposes. Stacks also collects pseudonymous, EU-hosted usage statistics in order to measure which features are used; they are tied to a random per-install identifier rather than to the account, contain no health data, and can be disabled in the app. Photo scans rely on an outside AI provider: a photo of a receipt, a meal, or a piece of gym equipment is sent to Google's Gemini API, and only once the notice describing it has been accepted. An optional subscription is billed by Apple through the App Store; payment details never reach Stacks.
Data controller
Stacks is operated by Aurélien Durier, an individual established in France, acting as data controller. Any request relating to personal data may be sent to the address at the bottom of this page.
Data collected
Creating an account and using Stacks involves storing:
- -Account: email address, hashed password, account creation date.
- -Profile: sex, year of birth, height, weight, activity level, fitness goal (cut/maintain/bulk).
- -Nutrition: recorded meals, food entries, recipes, daily targets.
- -Workouts: exercises, sets, reps, weights, workout templates, sessions.
- -Other activities: the type (running, walking, hiking, cycling, swimming, mobility, team sport, or other), the date, an optional duration and distance, and the name typed for an "Other" activity.
- -Body composition: bodyweight entries recorded over time.
- -Technical: session tokens, which keep the account signed in, and standard web-server access logs (IP address, timestamp, requested route) kept by the hosting provider for security and abuse prevention.
- -Pseudonymous usage analytics, in the app: which features and screens are used, recorded as plain counters and flags (e.g. "a workout set was logged", "the weekly review was opened"), plus the moments the app is installed, updated, opened, and sent to the background. Each event carries the device characteristics (manufacturer, model, screen size, OS, language, time zone), the app version, the distribution channel (App Store, TestFlight, or internal build), and the country, which the analytics provider derives from the IP address before discarding it. Screens are recorded by their route template ("/recipes/[id]"), never with the identifier of a meal, recipe, or workout. These events are tied to a random identifier generated on the device at installation, which is never linked to the Stacks account and is replaced on sign-out. They never contain meal, food, exercise, or bodyweight values. Once per installation, in the first days after it, the app asks Apple's AdServices service whether the installation followed an Apple Search Ads ad, and records the answer as one event: either that it did not, or the numeric identifiers of the campaign, ad group, keyword, and ad, with whether the ad was tapped or only viewed and whether the installation was a first download or a re-download. Apple gives this answer without the advertising identifier (IDFA) and without asking for tracking permission. Nothing is asked when analytics is switched off.
- -Audience measurement, on this website: the pages viewed and how long the visit lasts, the address of each page without its query string, the referring page, the campaign parameters and advertising click identifiers an incoming link carries (utm_*, gclid, fbclid and similar), and the browser, operating system, device type and screen size. No cookie and no local storage entry is kept, and the values typed into a form are never recorded. The IP address reaches the measurement provider, which uses it to compute an identifier that is regenerated every day, so a returning visitor is counted as a new one. Two named events record that the App Store badge was clicked and that the waitlist form was submitted, each carrying no information of its own beyond the page language.
- -AI features: the date on which the photo scan notice was accepted, a single record shared by every photo scan, and a timestamped entry per scan performed, used to enforce a usage cap. The items a receipt or meal photo scan detected are also kept, so a scan interrupted before its items were logged can be finished later; they are deleted once those items have been logged, and after seven days in any case. The photo itself is not stored, nor is the note that may accompany a meal photo.
- -Reminder emails: whether they are enabled, and the date consent was given, in order to send them and record when that consent was given; the date is cleared when they are turned off.
- -Subscription: the current subscription status (product, period, expiry, renewal state) and the related subscription events. Payment details (card numbers, billing address) never reach Stacks: Apple processes the payment.
- -Discovery channel: the answer, when one is given, to the optional question asked at signup on how Stacks was discovered, a single choice from a fixed list (App Store search, web search, Instagram, TikTok, YouTube, Facebook, another social network, a friend or family member, an ad, an article or podcast, other). No free text is collected.
The following are notcollected: contacts, the device's location (GPS or city), photo library, microphone, or any health data from Apple Health or Google Fit. The camera is used only on the user's initiative: for barcode scanning, where the image stays on the device and is never transmitted, and for receipt, meal and equipment scans, where the photo is transmitted to an AI provider as described below and is not retained.
Purposes and legal bases
For account, profile, nutrition, workout, activity, and body composition data, the legal basis is the performance of a contract(article 6.1.b): this data is necessary to operate the service that was signed up for. Profile data (sex, age, weight, height, activity level) is used solely to compute daily energy and macronutrient targets, and for no other purpose. The same basis covers the subscription status described under “Subscription” below, which is necessary to grant the features that were paid for.
For the usage analytics described above, the legal basis is the legitimate interest(article 6.1.f) in measuring how the app is used in order to improve it. This data is pseudonymous, not anonymous: the per-install identifier makes it possible to tell one installation's events apart from another's, even though nothing in them names anyone. It is therefore personal data, and the balance below is what makes that interest prevail.
- -Purpose: knowing which features are used and where the app is abandoned, in order to decide what to fix and what to build, and whether an Apple Search Ads campaign brings installations that keep using the app, in order to decide whether to keep paying for it. The data is used internally for that purpose only, never to target or personalize advertising, and is shared with no one other than the analytics provider acting as processor.
- -Necessity: this question cannot be answered from the account data itself, which records what was logged, not which screens were visited or where a path stopped. Collection is limited to what the question requires: counters, flags, generic screen names, device characteristics, and the country, which is what tells apart how the app is used in each market it is offered in.
- -Balance: the identifier is never linked to the account, and the analytics provider's identify function is never called. Before sending, the app keeps only booleans, counts, and a fixed list of known values, and no meal, food, exercise, or bodyweight value is ever passed to it. The IP address is used only to derive the country, then discarded by the provider rather than stored; the city, region, postal code, and coordinates it could also yield are deleted before the event is recorded. Processing stays in the European Union, events are deleted after 12 months, and analytics can be switched off at any time in Settings → Preferences, after which nothing more is sent.
Website audience measurement rests on the same legitimate interest(article 6.1.f): knowing how many people reach usestacks.app, where they arrive from, and whether they go on to the App Store. It is kept to what that purpose requires: nothing is stored on the visitor's device, the identifier is regenerated every day, no profile is built, and the data is never used for advertising nor shared with advertisers. A browser that sends the Do Not Track signal is not measured at all, and an objection may also be addressed to the contact address at the bottom of this page.
For the discovery channel, the legal basis is the legitimate interest (article 6.1.f) in knowing which channels bring people to Stacks, and which of them bring people who keep using it or subscribe, in order to decide where to invest. The question can be skipped, the answer is a single choice from a fixed list, and it is only ever read in aggregate: it is never used for advertising nor shared with anyone. The answer is also counted in the usage analytics described above, without being linked to the account.
For receipt scan and meal photo scan, the legal basis is explicit consent (article 6.1.a, and article 9.2.a for information liable to reveal dietary habits), collected before the first photo is analysed and described in the sections of the same name below.
For reminder emails, a prospecting communication under article L34-5 of the French Post and Electronic Communications Code (CPCE), the legal basis is consent(article 6.1.a), described under “Reminder emails” below.
Cookies and similar technologies
This website sets two cookies. Both are first-party: they are set by usestacks.app itself and are readable by no one else. None of them serves advertising, audience measurement, or tracking from one site to another, and no third party sets a cookie here.
- -NEXT_LOCALE, on the public pages: records the display language, so that the pages that follow are served in the language chosen. It holds a language code and nothing else, and it lasts for the browsing session.
- -The session cookie, set after signing in: keeps the account signed in from one page to the next, so that credentials are not requested again on every request. It holds a session token. The session lasts 30 days and is extended each time it is used; signing out ends it.
Under article 5(3) of the ePrivacy Directive, transposed in France by article 82 of the Data Protection Act, consent is required before anything is stored on a visitor's device, unless what is stored is strictly necessary in order to provide an online service the user has expressly requested. Both fall within that exemption: keeping an account signed in is necessary to the account area itself, and the CNIL lists interface personalisation cookies, such as a language or display choice, among those exempt where that personalisation is an intrinsic and expected part of the service. That is what the language cookie does, holding a single preference and no identifier.
That exemption concerns the storing of the cookie; the GDPR applies to the personal data involved regardless. For the session cookie, the legal basis is the performance of a contract (article 6.1.b): it is what makes an account usable. The language cookie carries no identifier and no personal data, only a language code; to the extent the GDPR applies to it, the basis is the legitimate interest (article 6.1.f) in presenting the site in the language it was last read in.
No consent banner is shown, because nothing here requires consent: the two cookies above are exempt, the website audience measurement described above runs without a cookie and writes nothing to the browser's local or session storage, and no advertising or cross-site tracking technology is loaded at all. These cookies can still be deleted or blocked from the browser's settings; blocking them signs the account out and returns the display language to its default.
Waitlist
An email address entered on the website in order to be notified (for example about the Android version or product news) is stored together with the page language and the sign-up date, for the sole purpose of sending news about Stacks. The legal basis is consent (article 6.1.a), given when the form is submitted. The waitlist is separate from the app account: no account is required to join, and joining does not create one. The address is kept until its removal is requested, or until the purpose of the waitlist ends (for example once the Android app has shipped), after which it is deleted. These emails are sent through Resend (EU region) and every message carries a one-click unsubscribe link. Deletion may be requested at any time at the address at the bottom of this page.
Push notifications
Enabling reminders and allowing notifications causes the device to register a push token, stored with the account for the sole purpose of delivering the reminders that were enabled (meals, weekly review, weigh-in) at the chosen times. The legal basis is consent (article 6.1.a), given when notifications are allowed and a reminder is enabled; it can be withdrawn at any time by switching reminders off in Settings → Notifications or by revoking the notification permission. The reminder text is generic and contains no personal or health data. Delivery goes through Expo's push service, which relays it to Apple's notification service; Expo does not store the reminder text. The token is kept solely to deliver these reminders, and is removed on sign-out and on account deletion.
Reminder emails
Stacks may email an account to encourage a return to the app after a period of inactivity. This is a prospecting communication under article L34-5 of the French Post and Electronic Communications Code (CPCE); it is optional and requires prior consent, given by switching on Reminder emails in Settings → Notifications, off by default, or by ticking a box, unchecked by default, at sign-up. The legal basis is consent (article 6.1.a). Consent is recorded on the account together with its timestamp, and can be withdrawn at any time the same way, or through the one-click unsubscribe link carried by every reminder email; withdrawing clears the timestamp and stops any further reminder email. The timestamp is kept only for as long as consent stands: it is cleared, rather than kept as a separate record, once consent is withdrawn or the account is deleted.
Receipt scan
Receipt scan is optional and requires prior consent, collected on a dedicated screen shown before the first photo is analysed. Nothing reaches the AI provider until that consent is given: a photo sent before it is refused by the Stacks server and discarded without being analysed.
When a receipt is scanned, the photo is transmitted to the Stacks server, then to Google's Gemini API, which identifies the item lines and estimates calories and macronutrients. The photo is not retained: it is processed in memory for the duration of that single request, then discarded. No email address, account identifier, profile data, or previously logged meal is transmitted with it.
The detected item names and the restaurant name are then sent to the same provider, which may run a Google Search, in order to refine the nutrition figures. The result is stored in a shared lookup table on the Stacks server, keyed by restaurant and item name only, with no link to any account.
The detected items are also kept on the Stacks server, attached to the account, so that a scan closed before its items were logged can be picked up again instead of costing another scan. They are deleted shortly after the items have been logged, and in any case seven days after the scan, the same window the usage cap counts over.
The API is used on its paid tier, under which Google does not use prompts, images, or responses to improve its products, and acts as a data processor under its Data Processing Addendum. It logs them for a limited period in order to detect abuse of its own service. Processing may take place outside the European Union; Google LLC is certified under the EU-US Data Privacy Framework, which covers that transfer.
The legal basis is explicit consent (article 6.1.a, and article 9.2.a for information liable to reveal dietary habits). The date of acceptance and a timestamped entry per scan are recorded in order to enforce a usage cap. Ceasing to use the feature ends any further transmission; erasure of the consent record and of the scan history may be requested at the address at the bottom of this page, and both are deleted along with the account.
Meal photo scan
Meal photo scan, which estimates the foods, portions, and calories on a photo of a meal, is optional and relies on the same prior consent as receipt scan: a single consent covers every photo scan, collected on a dedicated screen shown before the first photo of any kind is analysed. Nothing reaches the AI provider until that consent is given: a photo sent before it is refused by the Stacks server and discarded without being analysed.
When a meal is scanned, the photo is transmitted to the Stacks server, then to Google's Gemini API, which identifies the foods and estimates their portions, calories, and macronutrients. A short note may be added to describe what the photo cannot show (a sauce, a cooking method, a restaurant); it is limited to 200 characters and transmitted as written, together with the photo. Neither the photo nor the note is retained: both are processed in memory for the duration of that single request, then discarded. No email address, account identifier, profile data, or previously logged meal is transmitted with them.
The detected items are kept on the Stacks server, attached to the account, so that a scan closed before its items were logged can be picked up again instead of costing another scan. They are deleted shortly after the items have been logged, and in any case seven days after the scan, the same window the usage cap counts over.
The API is used on the same paid tier and under the same processor terms as described under “Receipt scan”, including for the transfer outside the European Union.
The legal basis is explicit consent (article 6.1.a, and article 9.2.a, since a photo of a meal is liable to reveal dietary habits). A timestamped entry per completed scan is recorded in order to enforce the usage cap, which receipt scan and meal photo scan share. Ceasing to use the feature ends any further transmission; erasure of the consent record and of the scan history may be requested at the address at the bottom of this page, and both are deleted along with the account.
Equipment scan
Equipment scan, which suggests exercises from a photo of a piece of gym equipment, is optional and relies on the same consent as the other photo scans. A single consent covers every photo scan: it is collected on a dedicated screen the first time any photo scan is used, and is not requested again for the others. Nothing is sent to the AI provider until that consent is given.
When equipment is scanned, the photo is transmitted to the Stacks server, then to Google's Gemini API together with the list of exercises in the Stacks library, which identifies the equipment and picks the exercises performed on it. The photo is not retained: it is processed in memory for the duration of that single request, then discarded. No email address, account identifier, profile data, or custom exercise is transmitted with it. A timestamped entry per scan is recorded in order to enforce a usage cap counted over a rolling seven days.
Ceasing to use the feature ends any further transmission; erasure of the consent record and of the scan history may be requested at the address at the bottom of this page, and both are deleted along with the account.
The legal basis is consent (article 6.1.a). The paid tier and the processor terms described under “Receipt scan” apply in the same way, including the transfer outside the European Union.
Subscription
Subscribing to Stacks Pro is optional. Payment is processed entirely by Apple through the App Store: card numbers and billing details never reach Stacks. For the payment itself, Apple acts as an independent controller, under its own privacy policy.
In order to know which account holds an active subscription, Stacks assigns the account a random purchase token, attaches it to the App Store purchase, and receives the subscription events (purchase, renewal, expiry, refund) directly from Apple's App Store server. No party other than Apple is involved, and these events carry only that token and the product details, never a name or an email address. The legal basis is the performance of a contract (article 6.1.b). These records are deleted with the account; Apple retains its own billing records under its own terms.
Recipients and subprocessors
Stacks relies on a limited number of third parties, strictly in order to operate the service. Most act as subprocessors, on Stacks's instructions. The identity providers below are the exception: they act as independent controllers for the sign-in they carry out.
- -Hosting: Hostinger (VPS, European Union). The Next.js application and the Postgres database run there.
- -Database backups: Cloudflare R2. A daily Postgres backup, encrypted at rest, retained for 30 days. International transfer covered by Cloudflare's Standard Contractual Clauses.
- -Email delivery: Resend, EU data region (Ireland). Used to send account, transactional, and reminder emails (the latter only with consent). Processed in the European Union and covered by Resend's GDPR-compliant DPA.
- -Crash and error reporting (iOS app and server, never the website): Sentry (EU region, hosted in Frankfurt, Germany). From the app, receives stack traces, device model, OS and app version. From the server, receives stack traces and the failing route. Both SDKs are configured to drop IP addresses, request bodies, and user identifiers before sending, so meals, workouts, bodyweight, and scan photos are never included. No reporter runs in the browser, so visiting this site sends nothing to Sentry.
- -Product analytics, iOS app only: PostHog (European Union region, eu.i.posthog.com). Receives pseudonymous usage events tied to a random per-install identifier: feature and screen usage as counters and flags, plus app installs and opens, the Apple Search Ads campaign an installation came from, if any, device characteristics (manufacturer, model, screen size, OS, language, time zone), app version, and distribution channel. Its identify function is never called, so events are not linked to an account, and meal, food, exercise, and bodyweight values are never sent. The IP address is used to derive the country only, then discarded. Processed in the EU and covered by PostHog's GDPR-compliant DPA. Events are kept for 12 months. Can be switched off in the app, under Settings → Preferences.
- -Audience measurement, website only: PostHog (European Union region, eu.i.posthog.com), loaded on the public pages of usestacks.app, never on the sign-in, account, or administration pages. It runs in cookieless mode: it keeps no cookie and no storage entry in the browser, and the visitor identifier is a hash computed on PostHog's side from the IP address and the browser, salted with a value that rotates every day. It receives the page addresses stripped of their query strings, the referring page, the campaign parameters, the browser and device characteristics, and the IP address. Its identify function is never called, no profile is created, and session recording is disabled. Processed in the EU and covered by PostHog's GDPR-compliant DPA. Enabling Do Not Track in the browser stops it. Events are kept for 12 months.
- -Food database lookup: Open Food Facts (French non-profit, EU-hosted). Queried when a barcode is scanned or a food is searched. The query and the IP address are visible to them; no account information is shared.
- -Install attribution, iOS app only: Apple (AdServices, Apple Distribution International Ltd., Ireland, for the European Union). Once per installation, while analytics is switched on, the app sends Apple a single-use token generated on the device, and Apple answers whether the installation followed one of Stacks's Apple Search Ads ads, with the identifiers of that campaign. The token carries no account information. Apple acts as an independent controller for its advertising measurement.
- -Push notifications: Expo (Expo Push service, operated by 650 Industries, Inc., United States) relays reminder notifications to Apple's notification service. It receives the device push token and the generic reminder text, which it does not store, and no personal or health data. 650 Industries self-certifies under the EU-US Data Privacy Framework, which covers the transfer to the United States.
- -Sign in with Apple: Apple (Apple Distribution International Ltd., Ireland, for the European Union). Involved only when that sign-in method is chosen. Apple confirms the identity and passes on an account identifier, plus, on the first sign-in only, the email address (or an Apple private relay address, if hiding it was chosen) and the name. Apple acts as an independent controller for the authentication itself.
- -Sign in with Google: Google (Google Ireland Ltd. for the European Union, Google LLC, United States). Involved only when that sign-in method is chosen. Google confirms the identity and passes on an account identifier, the email address, the name, and a profile picture URL that is discarded rather than stored. Google acts as an independent controller for the authentication itself. Google LLC is certified under the EU-US Data Privacy Framework, which covers the transfer outside the European Union.
- -AI photo reading (receipts, meals, and gym equipment): Google (Gemini API, Google LLC, United States). Involved only when a receipt, meal photo, or equipment scan is run. Receives the photo of the receipt, then the detected item names and the restaurant name, and returns the estimated nutrition; receives the photo of the meal with its optional note, and returns the detected foods and their estimated nutrition; or receives the photo of the equipment with the list of Stacks library exercises, and returns the matching exercises. No account identifier accompanies it. The paid tier is used, under which Google does not use this content to improve its products and acts as a data processor under its Data Processing Addendum, logging it briefly in order to detect abuse of its service. Google LLC is certified under the EU-US Data Privacy Framework, which covers the transfer outside the European Union.
No data is ever sold, and none is shared with advertisers or data brokers. Nothing recorded in the app is used to train AI models: the photo scans described above run on a paid API tier, under which the provider does not use the content it receives to improve its own products. The product analytics above is pseudonymous, never linked to an account, and used internally only, to improve Stacks.
Retention
Data is retained for as long as the account exists. Deleting the account from Settings → Account & data → Delete account permanently removes all associated data within 30 days, except the minimal records required by law, which are erased at the end of their statutory retention period. An account left untouched for two years is sent a warning email, and is permanently deleted 30 days later unless the app is opened again before then; opening the app, or an active Pro subscription, cancels the pending deletion.
Rights of the persons concerned
Under the GDPR, every user has the right to:
- -Access their data (Settings → Account & data → Download my data exports a JSON copy).
- -Rectify inaccurate data, which is directly editable in the app.
- -Erase the account and all related data (Settings → Account & data → Delete account).
- -Object to or restrict processing, including switching off usage analytics (Settings → Preferences).
- -Lodge a complaint with the CNIL (cnil.fr) should these rights not be respected.
These rights can be exercised directly in the app, or by writing to the address at the bottom of this page. Requests are answered within 30 days.
One limit applies to the usage analytics. Because its events are never linked to the account, and the per-install identifier is not displayed anywhere, Stacks has no means of finding the events of a given person, and so cannot export or erase them on request (article 11 of the GDPR). The rights that remain effective are the ones that do not require finding them: switching analytics off stops all further collection, signing out replaces the identifier, and every event is deleted after 12 months in any case.
Security
Passwords are hashed and never stored in clear text. Traffic between the app and the server is encrypted (HTTPS). Database backups are encrypted at rest. Access to production data is restricted to the operator and logged.
Minors
Stacks is not intended for persons under 16. Should an account have been created by a minor, a message sent to the address at the bottom of this page will lead to its deletion.
Changes
Any amendment to this policy is reflected in the effective date shown at the top of this page. Material changes are notified in the app before they take effect.
For any question about this policy, write to adurier.pro@gmail.com.