Daylit — Privacy
Daylit 2.0 · last updated 14 October 2026 · made by Erek Studio
This page says what Daylit 2.0 does with what you put into it. It was written from the app's code and the code of the gateway it talks to, and each statement carries a number that the table at the end ties to a file. Where something could not be checked in code, it is listed under "Not verified" instead of being claimed.
In short
- There is no account. Daylit does not ask for a name, an e-mail address or a phone number. [1]
- Events, notes, expenses, important dates, projects, files and plans are kept in a database on your phone. [2]
- Four things in the app are written by an AI model: a plan, an answer to a question about a day, a spending observation and a file Read. For each of those, the text of that one request leaves the phone. Apart from a backup file you choose to share, nothing else you log is sent by the app. [3]
- Before the first of them, Daylit asks. "Not now" sends nothing. [4]
- The gateway that passes the request on does not write its text to storage or to its logs. It does keep a few things that are not text, listed below with how long each is kept. [5]
- There are no ads and no analytics or crash-reporting kit in the app. [6]
What stays on the phone
- Everything you log by hand — events, notes, expenses, important dates, projects and the progress logged on them, attached files and the text read out of them, plans and your reflections on them — is stored in the app's own folder on the phone, in one database and one folder of file copies. Projects are never part of an AI request. [2]
- Answers the AI has written (a plan, a day answer, an observation) are stored there too, so opening them again sends nothing. [7]
- Two dates are kept on the phone for the store's rating prompt: the day Daylit was first opened and the day it last asked. The prompt is the App Store's or Google Play's own sheet; Daylit is not told what is chosen in it, and asks at most once in 120 days. [43]
- Search, totals, the month view, currency conversion, the capacity forecast and the "nothing saved on this day" reply are worked out on the phone. A day that holds nothing makes no request at all. [8]
- Your profile (day hours, focus window, capacity, tone, habits) is a file on the phone. It leaves only inside a plan request. [9]
- On Android, Daylit's data is excluded from Google's cloud backup and from device-to-device transfer. [10]
- On iPhone, Daylit does not exclude its folder from the phone's own backup. If you use iCloud Backup or back up to a computer, iOS puts Daylit's data in that backup as it does for other apps. That copy is made by iOS under your Apple account; Daylit's maker has no access to it. [11]
What leaves the phone, and when
Every AI request goes out through one door in the app, to Daylit's gateway, over HTTPS. The door asks for consent first and writes a row in the log on your phone afterwards. [12]
Each request also carries the task's name, a random id made for that one request (so a retry is not counted twice), the app's version, and a device token (see "What identifies an install"). [13]
Plan (plan)
Sent when you ask for a plan. It carries:
- your profile: when your day starts and ends, your focus window, when your energy fades, your capacity in hours, the tone you chose, and your daily habits (name, time, minutes);
- the language to write in, and which version you asked for (realistic, gentle, ambitious);
- what you typed into the planner for that day;
- that day's timed events as a list of times and titles: Daylit's own events, and — only while you have the phone calendar switched on — the phone calendar's events from the calendars you chose. Times and titles only: no notes, no places, no guests. All-day events are not sent;
- when your recent reflections lean one way, one fixed sentence saying your days have been running tighter, or lighter, than planned. [14]
Day question (day_answer)
Sent when you type a question about a day. It carries the question, the date, the language, and what that day holds, because the answer has to cite it:
- that day's events (time, title, and the event's note);
- that day's notes (the time written, title and text);
- that day's expenses (amount, currency, category, and the expense's note);
- up to six pages of the files attached to that day — the pages that best match the words of your question, or the opening pages when none match — with the file's name.
Long items are shortened to fit. Phone-calendar events are not part of a day question. A question about a day that holds nothing is answered on the phone and sends nothing. [15]
Spending observation (spending_insight)
Sent when you ask for the observation on a month. It carries totals, never entries:
- for each category you spent in: its name (one of the app's built-in categories), the month's total, the number of entries, and its three-month average when there is one;
- for each of those categories, how many entries fell on each weekday;
- the month's total, the previous month's total when there is one, the number of days with an entry, your home currency, the month, and the language.
No single expense, no amount of a single expense, no note and no date of an entry is in it. The gateway also rebuilds the request from these fields alone before passing it on, so a field that is not on this list does not reach the processor. [16]
File Read (document_analyse)
Sent when you press Read on a file. It carries the text of the pages that are read — the pages you chose, or as many from the start as fit — with the file's name, the date the file is attached to, the language, and a line saying which pages are covered. The text was extracted on the phone; the file itself is not uploaded. [17]
Requests that are not AI
These go to the gateway without the consent question, because they carry nothing you wrote:
- A device token. The gateway only answers a genuine copy of the app. To prove it is one, the app asks Apple (App Attest) or Google (Play Integrity) for an attestation and sends it to the gateway with its install identifier and, if you have subscribed, the store's receipt for the subscription. The gateway returns a token valid for 12 hours. This first happens when the app starts, not when you first use the AI. [18]
- The balance. At start, and again at a few later moments (for example after a purchase), the app asks the gateway how many free answers this install has left. [19]
- Exchange rates. When an expense needs a rate, the app asks the gateway for the rate table of a date. The request says which date and nothing about the expense; the conversion is done on the phone. [20]
Who processes it
The gateway is a Cloudflare Worker run by Erek Studio. For an AI request it adds the instructions for the task and passes the text on to one processor. The request it makes to the processor is built by the gateway: it holds the instructions and the text, and neither the install identifier nor any header your phone sent. [21]
<!-- processors:start (test/privacy/privacy_text_test.dart compares this list with the consent sheet's) -->
- DeepInfra (
deepinfra) — runs the DeepSeek model that writes the answer. Every AI request goes here first. - OpenAI (
openai) — only when DeepInfra cannot be reached. - Anthropic (
anthropic) — only when neither DeepInfra nor OpenAI can be reached.
<!-- processors:end -->
The reply says which of the three wrote it, and the log on your phone shows that name for every request. [22]
Others that take part, and what reaches them:
- Cloudflare runs the gateway and its storage, so everything sent to the gateway passes through Cloudflare's network. [23]
- Apple or Google issue the attestation, and the gateway asks the App Store or Google Play whether a subscription receipt is valid. Purchases themselves are made with the store; Daylit never sees a card. [24]
- The exchange-rate feed (
fawazahmed0/exchange-api, fetched through jsDelivr or its mirror) is contacted by the gateway, not by your phone, and is sent nothing about you. [25]
What the gateway keeps, and for how long
The gateway does not write the text of a request or of a reply to storage or to its logs. A reply is passed to your phone as it arrives. (For one case — a free day question — the reply is also held in memory until it ends, to see whether it found nothing so that the answer is not counted, and is dropped with the request.) [26]
What it does keep:
| What | Tied to | Kept for |
|---|---|---|
| The count of free answers used | install identifier | no expiry |
| For each free request that reached the count: its random id, how often it was tried, whether it was counted, and a keyed fingerprint (HMAC-SHA256) of the request | install identifier | no expiry |
| While such a request is in flight: a hold with the time it was placed | install identifier | until the reply ends, at most 2 minutes |
| A mark that this install has used Daylit 2 | install identifier | no expiry |
| The pairing of an attested device id with the install identifier | attested device id | no expiry |
| Whether a subscription was confirmed, whether it is a trial, and a marker of the billing period | install identifier | 13 hours |
| Counters of AI requests (per minute, per day) and of the model usage they caused (per day) | attested device id | 2 minutes, about 25 hours |
| A request counter per month (Pro only) | install identifier | about 37 days |
| Counters of device-token requests | IP address | 2 minutes, about 25 hours |
| A one-time challenge for the attestation | nothing | 5 minutes |
| One log line per AI request: app, free or Pro, task name, whether an answer was counted, which processor and model served it, app version | nothing | see "Not verified" |
About the fingerprint: it lets the gateway tell that a retry is the same request and not a new question. The text cannot be read back from it. Someone holding the gateway's secret key could use it to confirm an exact guess of a whole request, and nothing more. [27]
The exchange-rate route keeps nothing about who asked. [28]
There is no route that deletes the rows with "no expiry". See "Deleting".
What identifies an install
- The install identifier. On iPhone it is a random number made on first use and kept in the Keychain; iOS keeps Keychain entries when an app is removed, so it is the same after a reinstall. On Android it is a SHA-256 hash, made on the phone, of Android's
ANDROID_IDwith an app-specific salt; the rawANDROID_IDis not sent, and the hash is the same after a reinstall. (If Android reports no usableANDROID_ID, a random number is used instead.) This identifier is what the free answers are counted against. [29] - The attested device id. The gateway derives it from the attestation and uses it as the key of its request counters. [30]
- The device token carries both and expires after 12 hours. [31]
These are not your name or your e-mail address, and Daylit has neither. They are persistent identifiers of this install: requests from it can be counted as coming from the same install. They are not sent to the AI processors. [21]
Daylit does not read the advertising identifier. [6]
Consent, and withdrawing it
- The first time an AI request would be sent, a sheet says what leaves the phone and names the processors above. Allow sends; Not now sends nothing, uses no answer, and is not remembered — the next AI action asks again. [4]
- A given consent is stored on the phone together with the list of processors it was given for. If that list changes in a later version, the question is asked again. [32]
- To withdraw: You → AI consent → Withdraw. From then on nothing is sent until you allow it again. What was already sent stays sent. [33]
- Without consent everything you log by hand keeps working. [4]
The log on your phone
You → What left your phone lists every AI request that reached a processor: when, which of the four tasks, what kinds of item it carried and how many of each, how many characters, and the processor that served it. The log holds counts, not text. It can be cleared; clearing it recalls nothing. [34]
Reminders, calendar, files, backup
- Reminders are notifications scheduled on the phone. There is no push service and no notification server. The system's permission question appears when you first save something with a reminder, not at launch. [35]
- The phone calendar is only read. Access is asked when you switch it on, not at launch. On Android Daylit holds the permission to read the calendar and not the one to write it. On iPhone the system has no read-only level, so the permission is the one iOS calls full access; Daylit's code contains no call that creates, changes or deletes a calendar entry. Events are read from the phone each time they are shown and are not copied into Daylit's own events. One thing is kept: when you ask for a plan with the phone calendar on, the plan that comes back places those events as fixed blocks, and the plan is stored on the phone with their times and titles in it — so a backup of Daylit made afterwards contains them too. The only part that can leave the phone is the times and titles in a plan request, as described above. [36]
- Files are chosen with the system's file picker. Daylit keeps its own copy in the app's folder and reads the text out of it on the phone. A file leaves the phone only as the text of the pages of a Read or of a day question. [37]
- A backup is one file, made on the phone, holding every table of the database and the attached files. It is handed to the system's share sheet and goes wherever you send it. It is a plain zip, not encrypted: whoever has the file can read it. [38]
No ads, no analytics, no account
The app contains no advertising kit, no analytics or crash-reporting kit, and no sign-in. The app itself connects to one host: Daylit's gateway. Two links on the Pro screen — this page and the store's terms — open in your browser. [6] Subscriptions are bought through the App Store or Google Play. [24]
Deleting
- One thing at a time: events, notes, expenses, important dates, files and stored answers can each be deleted in the app, and the log can be cleared. A stored plan is replaced when you plan that day again; this version has no separate delete for a plan. [39]
- Everything on the phone: removing the app removes the database, the file copies, the profile and the consent record. On iPhone the Keychain entries stay (the install identifier, the device token, the last known balance, the subscription flag and receipt), because iOS keeps them when an app is removed. Backups you made, and an iOS device backup, are separate copies. [40]
- At the gateway: the counters expire on their own as listed above. The rows with no expiry — the count of free answers, the request ids and fingerprints, the "has used Daylit 2" mark and the device pairing — stay, and there is no function in the app or the gateway that deletes them. They hold no text and no name. A request to remove them can be sent to the address below; because there is no account and the app does not show its install identifier, such a request cannot at present be matched to an install. [41]
- At the processors: see "Not verified".
Children
Daylit is a general-audience app and is not directed at children.
Contact
Questions and requests: mustafasalimerek@gmail.com
If you are still using a version before 2.0
Versions before 2.0 showed rewarded video ads through Google AdMob. On iPhone they asked for permission to track first (App Tracking Transparency), and in the European Economic Area and the United Kingdom a consent form came first. AdMob received the device's advertising identifier where that was allowed, an approximate location derived from the IP address, and ad-interaction data. Version 2.0 contains no advertising and none of that software; updating the app ends it. This section will be removed once versions before 2.0 are no longer offered. [42]
Changes
When this text changes, the date at the top changes with it. If the list of processors changes, the app asks for consent again.
Not verified
These could not be checked in the app's or the gateway's code, so nothing above relies on them:
- What DeepInfra, OpenAI and Anthropic keep. How long a processor holds a request, whether it reviews requests for abuse, and whether it uses them to train models are set by its own terms and by Erek Studio's agreement with it, not by code. The earlier version of this page said processors do not train on the content; that sentence has been removed until it is confirmed against the current terms of all three.
- How long the gateway's log lines are kept. The code turns on Cloudflare's log storage and turns off its per-request records (address, URL, headers). The retention period is Cloudflare's setting for the account.
- That no error message can carry a fragment of text into a log line. Every log statement in the gateway was read and none prints request or reply text; error messages raised by the runtime itself were not traced exhaustively.
- What Cloudflare records at its own network edge, outside the gateway's code, and whether any network-level detail of your connection is visible to a processor. (The gateway's code forwards none.)
- That the deployed gateway is this code. The gateway was read on its branch
v2(commita6f0e16); its contract file says it was not yet deployed on 11 October 2026. Deployment settings that are not in the repository — notablyDEEPSEEK_BASE_URL, which could point the first processor at another host — cannot be seen from code. If that were ever set, the log on your phone would show the other host's name. - iOS backup and Keychain behaviour are stated from what the code does not do (it sets no backup exclusion) and from the platform's documented behaviour; they were not tested on a device for this text.
- Apple's and Google's handling of attestation requests and purchases.
Statement → source
Paths without a prefix are in the app's repository. gateway: is erek-ai-backend on branch v2.
| # | Statement | Source |
|---|---|---|
| 1 | No account, no name or contact field | pubspec.yaml (no sign-in package); lib/data/gateway/token_store.dart |
| 2 | Logged items live in one database and one file store on the phone; projects are not part of any AI request | lib/data/db/database.dart; lib/data/db/tables.dart; lib/data/files/file_store.dart; lib/data/repositories/projects_repository.dart; lib/domain/ask/day_sources.dart (no project source) |
| 3 | Four AI tasks, one door | lib/data/gateway/chat_request.dart; lib/data/gateway/ai_door.dart |
| 4 | Consent is asked before the first send; Not now sends nothing and is not stored | lib/data/gateway/ai_door.dart; lib/features/consent/consent_controller.dart; lib/features/consent/consent_sheet.dart |
| 5 | The gateway stores no request or reply text | gateway:src/routes/v2/chat.ts; gateway:src/lib/settle.ts; gateway:src/durable/units.ts |
| 6 | No ad, analytics or crash kit; no advertising identifier; one host and two links | pubspec.yaml; pubspec.lock; lib/core/env.dart; lib/data/gateway/gateway_dio.dart; lib/features/paywall/paywall_screen.dart; android/app/src/main/AndroidManifest.xml; ios/Runner/PrivacyInfo.xcprivacy |
| 7 | Answers are stored on the phone | lib/data/db/tables.dart; lib/data/repositories/asks_repository.dart; lib/data/repositories/observations_repository.dart |
| 8 | Search, totals, conversion and the empty-day reply are local | lib/data/repositories/search_repository.dart; lib/domain/month_spend.dart; lib/data/rates_service.dart; lib/features/ask/ask_service.dart |
| 9 | The profile is a local file | lib/features/profile/profile_controller.dart; lib/domain/models/profile.dart |
| 10 | Android backup and transfer excluded | android/app/src/main/AndroidManifest.xml; android/app/src/main/res/xml/data_extraction_rules.xml |
| 11 | iOS: no backup exclusion is set | lib/data/db/database.dart; ios/Runner/AppDelegate.swift (not verified on a device) |
| 12 | One door, HTTPS, consent first, log row after | lib/data/gateway/ai_door.dart; lib/core/env.dart |
| 13 | Task, request id, version, token on each request | lib/data/gateway/chat_request.dart; lib/data/gateway/gateway_dio.dart; lib/data/gateway/gateway_client.dart |
| 14 | What a plan request carries | lib/domain/prompt_builder.dart; lib/domain/models/profile.dart; lib/domain/agenda.dart; lib/domain/system_events.dart; lib/providers.dart |
| 15 | What a day question carries | lib/domain/ask/day_request.dart; lib/domain/ask/day_sources.dart; lib/data/repositories/ask_day_repository.dart; lib/features/ask/ask_service.dart |
| 16 | A spending observation carries totals only; the gateway rebuilds it | lib/domain/spending_insight.dart; gateway:src/lib/spending.ts; gateway:src/routes/v2/chat.ts |
| 17 | What a file Read carries | lib/domain/file_read.dart; lib/data/files/file_read_service.dart; lib/data/files/file_extractor.dart |
| 18 | Device token: attestation, install id, receipt; 12 hours; at start | lib/data/gateway/token_store.dart; lib/data/gateway/attestor.dart; lib/main.dart; gateway:src/routes/token.ts |
| 19 | Balance request | lib/features/paywall/units_controller.dart; lib/main.dart; gateway:src/routes/v2/units.ts |
| 20 | Rates request carries a date only | lib/data/gateway/rates_api.dart; lib/data/rates_service.dart |
| 21 | The processor gets the task instructions and the text, no identifier | gateway:src/providers/openai.ts; gateway:src/providers/anthropic.ts |
| 22 | Routing order; the reply names who served it | gateway:src/config.ts (APP_CONFIG.planner); gateway:src/providers/index.ts; lib/features/consent/consent_store.dart |
| 23 | Cloudflare runs the gateway | gateway:wrangler.toml |
| 24 | Attestation and receipt checks; store purchases | gateway:src/auth/appattest.ts; gateway:src/auth/playintegrity.ts; gateway:src/middleware/receipt.ts; lib/features/paywall/iap_service.dart |
| 25 | Rate feed is fetched by the gateway | gateway:src/routes/v2/rates.ts |
| 26 | Replies are streamed; a free day answer is held in memory to be judged | gateway:src/lib/settle.ts; gateway:src/lib/dayanswer.ts |
| 27 | What is kept and for how long | gateway:src/durable/units.ts; gateway:src/middleware/units.ts; gateway:src/middleware/migration.ts; gateway:src/routes/token.ts; gateway:src/middleware/ratelimit.ts; gateway:src/routes/challenge.ts; gateway:src/routes/v2/chat.ts |
| 28 | The rates route keeps nothing about the caller | gateway:src/routes/v2/rates.ts |
| 29 | The install identifier on each platform | lib/data/gateway/token_store.dart |
| 30 | The attested device id | gateway:src/auth/appattest.ts; gateway:src/auth/playintegrity.ts; gateway:src/auth/gate.ts |
| 31 | The token's contents and life | gateway:src/routes/token.ts; gateway:src/lib/jwt.ts |
| 32 | Consent is stored with its processor list | lib/features/consent/consent_store.dart |
| 33 | Withdrawal | lib/features/consent/consent_controller.dart; lib/features/you/you_screen.dart |
| 34 | The log: columns, when a row is written, clearing | lib/data/db/tables.dart; lib/data/gateway/ai_door.dart; lib/features/ask/outbox_screen.dart |
| 35 | Reminders are local | lib/features/reminders/local_notifications_gateway.dart; lib/features/reminders/reminder_permission.dart |
| 36 | Calendar: only read, asked on switch-on, not copied into events; kept inside a plan made from them (lib/features/history/history_controller.dart, the plan is stored whole) | lib/data/syscal/calendar_source.dart; lib/data/syscal/plugin_calendar_source.dart; android/app/src/main/AndroidManifest.xml; ios/Runner/Info.plist; lib/domain/system_events.dart |
| 37 | Files: picker, local copy, local text | lib/data/files/file_picker_port.dart; lib/data/files/file_store.dart; lib/data/files/file_extractor.dart |
| 38 | Backup: one unencrypted zip through the share sheet | lib/data/backup/backup_format.dart; lib/data/backup/backup_codec.dart; lib/data/backup/backup_service.dart; lib/features/backup/backup_screen.dart |
| 39 | What can be deleted in the app | lib/data/repositories/agenda_repository.dart; lib/data/repositories/expenses_repository.dart; lib/data/repositories/dates_repository.dart; lib/data/repositories/documents_repository.dart; lib/data/repositories/asks_repository.dart; lib/data/repositories/ask_day_repository.dart |
| 40 | What removing the app removes, and what the Keychain keeps | lib/data/db/database.dart; lib/features/consent/consent_store.dart; lib/data/gateway/token_store.dart; lib/features/paywall/units_controller.dart; lib/features/paywall/iap_service.dart (Keychain behaviour not verified on a device) |
| 41 | No deletion route; the install identifier is not shown | gateway:src/index.ts; lib/features/you/you_screen.dart |
| 42 | Versions before 2.0: rewarded AdMob ads, the tracking prompt on iPhone, the consent form | main:pubspec.yaml (google_mobile_ads 9.0.0, version 1.0.4); main:lib/monetize/ads_service.dart; main:lib/monetize/ad_consent.dart; main:ios/Runner/Info.plist (NSUserTrackingUsageDescription) |
| 43 | The rating prompt: two dates on the phone, the store's own sheet, at most once in 120 days | lib/features/rating/rating_moment.dart; lib/features/rating/rating_record.dart; lib/features/rating/review_prompt.dart |