FoodNoteBook
Contents
- Summary
- 1. Controller
- 2. What this app actually does (the technical basis of this policy)
- 3. Categories of data processed
- 4. Legal bases
- 5. What else is involved: server, sign-in, third parties and purchases
- 6. Recipients at a glance
- 7. Retention period
- 8. Your rights
- 9. Children
- 10. Data security
- 11. Automated decision-making
- 12. Changes to this policy
Privacy Policy
Last updated: 6 September 2026
*This is an English translation provided for convenience. The German version at https://mk-sd.com/foodnotebook/privacy is the authoritative text; in case of any discrepancy, the German version prevails.*
Summary
FoodNoteBook is different from a purely local app: to make AI meal recognition work, to make your account show the same data on several devices, and to manage a subscription, the operator runs its own server, and several third-party services are involved. This summary names the main points; roles and legal bases are in sections 2, 5 and 6.
- An account is required. You sign in with an email address and password, your Google account, or Sign in with Apple. Your entries live server-side in a database, hosted on Fly.io servers in Frankfurt am Main, Germany.
- Photos and spoken or typed descriptions of your meals and activities are sent to the Google Gemini API to estimate calories and nutrients, and photos are then kept together with the meal entry, not discarded. These estimates are an AI's approximation, not a measurement and not medical advice (section 2 and the health notice below).
- Apple Health (HealthKit): if you connect it, the app reads and writes your body weight only, nothing else. That is health data under Article 9 GDPR and requires your explicit consent through the iOS permission prompt.
- Emails (registration confirmation, password reset, support replies, and occasional summaries and reminders) are sent through the Resend service.
- Purchases run through two separate paths: Apple's App Store purchase (StoreKit) or, if you subscribe through the website, the payment processor Stripe. In neither case does the operator ever see your payment details itself.
- You can currently delete your account, and export your data, yourself through the account settings on the FoodNoteBook website. The iPhone app itself has no dedicated button for this today, only "Log out"; deletion is nonetheless always available by emailing the operator, see section 8.
1. Controller
Maximilian Kuchlbauer
Flurstr. 1
84524 Neuötting
Germany
Email: maximilian.kuchlbauer@gmail.com
No data protection officer has been appointed.
The app also has a product support mailbox (support@foodnotebook.org) that reaches the operator; for exercising your rights under the GDPR, the address above is the one that matters.
2. What this app actually does (the technical basis of this policy)
This section describes what was verified against the server source (server/src) and the iPhone app source (ios-native/Sources), not what would be desirable.
- A server, not a purely local device. Unlike a purely local app, FoodNoteBook sends your entries to a server operated by the provider (Node.js/Express, a PostgreSQL database), so the same data appears on every device and so the AI analysis can happen at all. The server runs on Fly.io, physical server location Frankfurt am Main, Germany (
primary_region = 'fra'in the configuration); Fly.io, Inc. itself is a US company. Details and legal basis in sections 5.1 and 6. - Account and sign-in. Full use of the app requires an account, either with an email address and a self-chosen password (the password is stored hashed, never in plain text), with Google sign-in (OAuth, via
google-auth-library), or with Sign in with Apple (Apple's own signed identity token is verified, without the operator ever receiving a password). On email registration the server sends a confirmation link (double opt-in); the server stores only the cryptographic hash of the confirmation code, never the code itself. Older guest and demo sign-in paths are marked in the code as being phased out and are not intended for new app versions. - AI estimation of meals and activities. When you photograph, speak, or type a meal or a sporting activity, the server sends the photo or the text to Google's Gemini API (
server/src/services/ai_service.js), which returns a name and estimated calories and macronutrients. These are AI estimates, not measurements. For spoken entries, the app first converts speech to text on the device itself (Apple'sSFSpeechRecognizer,ios-native/Sources/Core/SpeechRecognizer.swift); in that case only the recognised text, never the audio recording, goes to the server and to Google. The app limits free entries per day, and the server separately caps the total cost of AI requests per day and per account. - Photos are stored, not only used for analysis. An uploaded meal photo is kept on the server, and its file path is permanently linked to the meal entry and therefore to your account (
server/src/routes/meals.js,server/src/services/storage.js) until you delete that entry or your account. There is no function that automatically removes the photo after AI analysis. Per the code reviewed here, the file by default sits on the disk of the same server in Frankfurt; the code also supports an external object store (S3), which was not active in the configuration values inspected. - Apple Health (HealthKit): body weight only. If you connect Apple Health, the app reads and writes your body weight value only (
ios-native/Sources/Core/HealthKitManager.swift). No workouts, no heart rate, no other health data is read or written, even though the system permission dialog is worded more broadly for historical reasons. Nothing happens without your explicit approval in that dialog. - Camera, photo library and microphone are requested so you can photograph a meal, pick an existing photo, or log a meal by voice; without your approval in the iOS dialog, the app uses none of these.
- Push notifications. If you allow notifications, the app registers an Apple push device token with the server, stored linked to your account, to deliver reminders. Delivery itself runs through Apple's push service (APNs).
- Purchases through two paths. In the iPhone app, the "FoodNoteBook Pro" subscription runs through Apple's in-app purchase (StoreKit 2); the server checks Apple's signed purchase receipts without any payment data reaching the operator. If you subscribe through the website instead, payment runs through Stripe; here too the operator sees no card data, only the payment confirmation from Stripe.
- Email delivery. Registration confirmation, password reset, support replies, and occasional summary and reminder emails are sent through the Resend service (
server/src/services/emailService.js). If you open or click such an email, the server records this server-side (time, IP address, link clicked), linked to the campaign and, where known, to your account (server/src/routes/track.js), to know which emails actually arrive and get read. - No advertising or analytics SDKs in the app itself. No analytics, crash-reporting, or advertising libraries were found in the reviewed iPhone app (no Firebase, no Adjust/AppsFlyer/Mixpanel-style library). Earlier purchase handling through RevenueCat is switched off: purchases have run through StoreKit 2 with server-side verification since that migration, and the RevenueCat columns in the database are, per the code's own comment, kept only for legacy rows and no longer written. This policy concerns the app; the older foodnotebook.org website, which this policy is meant to replace, is not the subject of this document.
- Self-service export and deletion exist server-side, but are not equally reachable from every channel. The server offers a data export and a full account deletion; both are reachable from the account settings on the FoodNoteBook website. In the reviewed iPhone app interface itself there is currently no button for either, only "Log out". See section 8 for the path that is always available regardless: emailing the operator.
3. Categories of data processed
| Category | Examples | Purpose | Storage location |
|---|---|---|---|
| Account data | Email address, password hash (for email sign-in), name, Google or Apple identifier (for sign-in through those), language setting | Sign-in, account management | Server database (Fly.io, Frankfurt) |
| Profile and goals | Age, height, weight, target weight, activity level, calorie and macro goals, training days | Calculating a calorie goal, personalisation | Server database |
| Meal and activity entries | Name, calories, macronutrients, time, entry type (food/exercise), duration | Core function: nutrition and activity diary | Server database |
| Meal photos | Photos taken or selected by the user | AI estimation of nutrients, then kept with the entry (see section 2) | Server (file storage, by default on the same machine as the database) |
| Health data under Article 9 GDPR | Body weight from Apple Health, if connected | Reconciling with the app's own weight entries | HealthKit on the device, and additionally as an ordinary measurement in the server database |
| Body measurements | Body measurements you enter manually | Progress display | Server database |
| Device token for notifications | Apple push device token | Delivering reminders | Server database, forwarded to Apple (APNs) |
| Email interaction | Time an email was opened/clicked, IP address, link clicked, campaign | Knowing whether system emails arrive; effectiveness of reminders | Server database |
| Purchase and subscription data (App Store) | Product identifier, purchase status, term | Unlocking FoodNoteBook Pro | At Apple; the server only reads the unlock status |
| Purchase and subscription data (website) | Stripe customer and subscription identifier, payment status | Unlocking FoodNoteBook Pro through the website path | At Stripe; the server stores only the identifier and status, no card data |
| In-app usage events | Fixed event names from a closed list, such as "plus button tapped", "AI analysis started", "AI analysis failed", plus a short failure code, the input kind (text, photo, voice) and a duration in milliseconds. No content: no meal text, no photo, no free text of any kind. | Finding out where the app stops making sense to people | Server database |
| Support messages | Message you write, email address | Handling your request | Server database |
The app does not ask for your location, your contacts, or your calendar, and does not read an advertising identifier.
On the usage events in particular, because they are the one category that is not a feature you asked for: there is no additional identifier. No install id, no device id, no advertising id. Events are attached to the account you already have, and only while you are signed in; signed out, no event is created. Which names and which extra fields may be stored at all is fixed in a closed list on the server, so the app cannot record anything else. No third party analytics service is involved; the rows stay in the same database as the rest of your entries.
4. Legal bases
- In-app usage events: Article 6(1)(f) GDPR (legitimate interest in finding out where the app is not understood and therefore abandoned). The events contain no content and serve only to improve the app. You may object to this processing under Article 21 GDPR; write to the address in the imprint.
- Account management, profile, entries, AI analysis, photo storage: Article 6(1)(b) GDPR (performance of the usage contract for the app).
- Google or Apple sign-in: Article 6(1)(b) GDPR; you choose which path to use at every sign-in.
- Health data from Apple Health (body weight) under Article 9 GDPR: exclusively your explicit consent under Article 9(2)(a) GDPR, expressed technically through the iOS permission prompt. Without that approval, no connection to Apple Health is made. Revocable at any time via "Disconnect" in the app or via the Health permissions in iOS Settings.
- Purchases (App Store and website): Article 6(1)(b) GDPR. For the App Store path, the purchase contract is concluded between you and Apple (section 5.5); for the website path, between you and the operator, with Stripe as payment processor (section 5.6).
- Transactional emails (registration, password reset, support): Article 6(1)(b) GDPR.
- Occasional summary and reminder emails: Article 6(1)(f) GDPR (legitimate interest in informing you about your own, self-logged nutrition data and reminding you before a subscription ends), or, where you agreed to this at registration, Article 6(1)(a) GDPR. You can object to any such email via the unsubscribe link it contains.
- Recording email opens and clicks: Article 6(1)(f) GDPR (legitimate interest in checking deliverability and function of the operator's own email sending). This classification is not conclusively settled; whether detecting email opens additionally requires separate consent is a question this policy leaves open and that a lawyer should answer (see
README.mdin this directory). - Push notifications: Article 6(1)(a) GDPR (your approval in the iOS permission prompt). Revocable via iOS notification settings.
- Storage on your device (§ 25 TDDDG): Where the app stores credentials or cached content on your device, this is strictly necessary to provide the function you explicitly want (staying signed in, offline viewing of already-loaded data), and falls under the exception in § 25(2) no. 2 TDDDG.
- Visiting this website: Article 6(1)(f) GDPR (legitimate interest in technically flawless and secure delivery of the page).
5. What else is involved: server, sign-in, third parties and purchases
For a purely local app, this section would be short. FoodNoteBook needs a server and several third-party services for its core function; they are listed individually here.
5.1 Server and hosting
The server runs on infrastructure from Fly.io, Inc., physical server location Frankfurt am Main, Germany (primary_region = 'fra'). Fly.io processes all the data listed in section 3, as a processor under Article 28 GDPR, while it is stored with the operator. Fly.io, Inc. itself is headquartered in the US; even though the server itself is in the EU, a transfer during support or maintenance access from a third country cannot be excluded. The operator bases such a transfer on the European Commission's Standard Contractual Clauses; a signed data processing agreement with Fly.io was not part of the material reviewed for this policy and remains for the operator to add (see README.md).
5.2 AI provider (Google Gemini API)
To estimate calories and nutrients from a photo or a text, the server sends what you submit to Google LLC's Gemini API, USA. Google processes this content as a processor under Article 28 GDPR to return the analysis result. A transfer to the US takes place, based on the European Commission's Standard Contractual Clauses. The server caps the daily number and cost of such requests per account and overall.
5.3 Signing in with Google or Apple
If you sign in with your Google account, the server receives your email address, name, and a Google account identifier from Google to create or recognise your FoodNoteBook account. If you sign in with Sign in with Apple, the server verifies an identity token signed by Apple; depending on your choice at first sign-in, Apple passes on either your real email address or an Apple-generated relay address. In both cases, Google and Apple respectively process the sign-in data as independent controllers under their own privacy policy; the operator has no influence over that processing.
5.4 Email delivery (Resend) and email tracking
Registration confirmation, password reset, support replies, and occasional summary and reminder emails are sent through Resend, Inc., USA. Resend processes your email address, name, and the content of each message as a processor under Article 28 GDPR. A transfer to the US takes place, based on the European Commission's Standard Contractual Clauses.
Every email the server sends contains an invisible marker or a redirect link that lets the server detect whether and when you opened it or clicked a link inside it; the result is stored linked to the campaign and, where the email went to an existing account, to that account. The purpose is checking deliverability and function of the operator's own email sending, not selling this information to third parties.
5.5 Purchases through the App Store (StoreKit)
FoodNoteBook Pro can be subscribed to as an in-app purchase through Apple (product identifiers M1 monthly, Y1 yearly in the app configuration). The purchase contract is concluded between you and Apple, not with the operator of this app. The server only verifies Apple's own signed purchase confirmation (StoreKit 2) to unlock Pro status; it receives neither your name nor your payment data from Apple. Apple Inc. or Apple Distribution International Ltd. processes the purchase, payment, and device information as an independent controller, not as a processor for the operator. Apple's own privacy policy applies (https://www.apple.com/legal/privacy/).
5.6 Purchases through the website (Stripe)
If you subscribe to FoodNoteBook Pro through the account settings on the FoodNoteBook website instead, payment runs through Stripe. Unlike the App Store path, here **the operator of this app is the contracting party for the subscription**; Stripe processes the actual payment data (card data or a comparable payment method) as an independent controller for payment processing. The server itself receives from Stripe only a customer and subscription identifier and the payment status (active, cancelled, end date), no card data. See the Terms of Use and the Right of Withdrawal for this app for details on price, cancellation, and withdrawal for this path.
5.7 Push notifications (Apple)
If you allow notifications, the app transmits a device token to the server, which stores it together with your account identifier and passes it on to Apple's push service (APNs) to deliver reminders. Apple processes this delivery as an independent controller under its own privacy policy.
5.8 Your device's backup
Like any other app, FoodNoteBook is part of your iPhone's iCloud or computer backup, if you have one enabled. This concerns the app itself (settings, cached content), not the server's database, which exists independently of your device backup. Apple, or your own computer, is responsible for this backup, not the operator.
5.9 Visiting this website
The legal texts linked from the app, and this policy itself, are delivered through mk-sd.com, operated via Cloudflare, Inc. as a processor under Article 28 GDPR. Cloudflare processes technically necessary connection data (in particular IP address, time of the request, address requested) to deliver the page and defend against attacks. This page sets no cookies and includes no analytics or advertising tools. This policy does not concern the older foodnotebook.org website, which uses its own, separate tools and which this policy is meant to replace.
5.10 If you email the operator
If you write to maximilian.kuchlbauer@gmail.com or to the app's support address, the operator processes your email address and the content of your message to answer it. The legal basis is Article 6(1)(b) GDPR where it concerns the app or your subscription, otherwise Article 6(1)(f) GDPR.
6. Recipients at a glance
This table summarises who, from sections 2 and 5, receives which data in which role.
| Recipient | Role | What data | Legal basis / third-country transfer |
|---|---|---|---|
| Apple Inc. / Apple Distribution International Ltd. | Independent controller | App Store purchases, Sign in with Apple, notification delivery (APNs), device backup | Article 6(1)(b) GDPR; Apple's own privacy policy |
| Google Ireland Limited / Google LLC | Independent controller for sign-in data | Email address, name, Google account identifier, for Google sign-in | Article 6(1)(b) GDPR; Standard Contractual Clauses for transfer to the US |
| Google LLC (Gemini API) | Processor | Meal photos, typed or speech-recognised text, for nutrient estimation | Article 6(1)(b) GDPR; Standard Contractual Clauses |
| Resend, Inc. | Processor | Email address, name, message content, open/click events | Article 6(1)(b), partly (f) GDPR; Standard Contractual Clauses |
| Fly.io, Inc. | Processor (hosting) | All account data listed in section 3, while stored | Article 6(1)(b) GDPR; server location EU (Frankfurt), company headquartered in the US |
| Stripe (Stripe, Inc. / Stripe Payments Europe, Ltd.) | Independent controller for payment processing | Email address, name, payment data, for the website purchase path | Article 6(1)(b) GDPR |
| Cloudflare, Inc. | Processor (website delivery) | IP address, time and address of visits to this legal text | Article 6(1)(f) GDPR; Standard Contractual Clauses |
Beyond this, no data is shared with third parties, in particular not with advertising networks, and no data is sold. As described in section 2, RevenueCat is no longer an active recipient.
7. Retention period
- Account and profile data, entries, photos: until you delete the individual entry or your account. For photos, the limitation from section 2 applies: deleting an entry or an account removes the database record; whether the underlying image file on the server is also deleted at that point could not be confirmed from the code reviewed here (see
README.md). - Email verification and password reset tokens: expire automatically after a short time (verification 24 hours, password reset 1 hour) and are in any case only ever stored as a hash on the server.
- Email open and click events: as long as the rest of the account data, since they belong to the same database; no separate automatic deletion period was apparent in the code reviewed.
- Push device tokens: until you turn off notifications, sign out, or delete your account.
- Purchase data: for the App Store path, exclusively with Apple; for the website path, with the operator for the duration of the contract and the statutory retention periods for payment records.
- Support messages: until the request is resolved, and afterwards only as long as a retention obligation requires.
8. Your rights
You have the rights under the GDPR to access (Article 15), rectification (Article 16), erasure (Article 17), restriction of processing (Article 18), data portability (Article 20), and objection (Article 21).
How these work in practice for this app:
- Rectification and deletion of individual entries (Articles 16, 17): directly in the app, by editing or deleting the individual meal, activity, body measurement, or habit.
- Access and data portability (Articles 15, 20): a full export of your account data as a file is already implemented server-side and reachable through the account settings on the FoodNoteBook website.
- Deletion of the entire account (Article 17): this function is also implemented server-side and reachable through the account settings on the FoodNoteBook website. In the iPhone app version reviewed here, there is no dedicated button for this, only "Log out". If you want to delete your account and cannot reach the website, email maximilian.kuchlbauer@gmail.com: the operator will then trigger the deletion function that already exists server-side on your behalf. This difference between the web and the app is known to the operator and noted as an open item (see
README.md). - Restriction and objection (Articles 18, 21): write to the email address above; this applies in particular to objecting to summary or reminder emails, which you can also unsubscribe from via the link in each such email.
- Purchase data: to be exercised against Apple for the App Store path (section 5.5); via the email address above for the website path.
- Withdrawing consent (Article 7(3)): disconnect the HealthKit connection via "Disconnect" in the app or via the Health permissions in iOS Settings; turn off notifications via iOS Settings; object to a marketing email via its unsubscribe link.
- Right to complain (Article 77): you can lodge a complaint with a data protection supervisory authority, in particular the one responsible for where you live. The authority responsible for the operator is the Bayerisches Landesamt für Datenschutzaufsicht (BayLDA), Promenade 18, 91522 Ansbach, Germany.
9. Children
Using FoodNoteBook requires a minimum age of 16 under this app's Terms of Use; younger users may only use it with the express consent of a parent or legal guardian. The app does not target children specifically.
10. Data security
Connections between the app and the server are encrypted (HTTPS). Passwords are stored hashed, never in plain text. Verification and reset codes are likewise stored only as a hash. Fly.io's security measures apply to the server infrastructure as its operator; measures the operator itself has implemented beyond that were not separately verified as part of this review.
11. Automated decision-making
The calorie and nutrient estimates returned by the Gemini API are an informational result of an AI analysis, not an automated decision with a legal effect or a similarly significant effect on you within the meaning of Article 22 GDPR: the app decides nothing about you, it estimates a nutrient value that you can edit or delete in every entry. No profiling within the meaning of Article 22 GDPR takes place.
12. Changes to this policy
This policy describes the state of the app as of the date given above. It will be updated as soon as the processing described here changes, in particular on a change of AI provider, email delivery service, hosting provider, or payment processor, on the introduction of further HealthKit data types, or once the iPhone app gets its own account deletion function.
The current version is available at https://mk-sd.com/foodnotebook/privacy. The Terms of Use are available at https://mk-sd.com/foodnotebook/terms, the Right of Withdrawal at https://mk-sd.com/foodnotebook/withdrawal.
*This policy describes the data processing verified against the source code of the server and the app as of 6 September 2026. It is not legal advice and does not replace a lawyer's review. Open items, where either the operator still needs to add something or a lawyer should be asked, are collected in README.md in this directory.*