Privacy Policy
Privacy Policy
TL;DR. Candela doesn't ship analytics, advertising, or tracking code. Nothing leaves your device unless you explicitly turn on a feature that requires the network (signing in for sync, browsing a fiction backend, downloading a voice). Uninstalling the app deletes everything stored locally; you can delete cloud-synced data via the in-app "Delete cloud data" action.
Effective date: 2026-07-10
App: Candela (org.techempower.candela)
Publisher: TechEMPOWER (501(c)(3) nonprofit, operating Candela)
Maintainer: JP Hein (jp@jphein.com)
Contact for privacy questions: jp@jphein.com
1. What Candela does
Candela is an Android app that reads text aloud using on-device neural text-to-speech voices. It fetches text from the fiction backends you opt into — Royal Road, RSS feeds, Notion, Wikipedia, EPUBs on your device, and a few dozen more — and renders that text into audio. It is free, ad-free, subscription-free, and open-source (GPL-3.0).
2. What we collect
By default, Candela collects nothing. Out of the box, the app has no account, no telemetry, no crash reporter, no analytics SDK, and no advertising identifier access. You can install and use it offline (with already-downloaded voices) and nothing about your usage leaves the device.
A few features collect or transmit data only when you turn them on:
2.1 Sync (optional)
If you opt into cross-device sync (Settings → Sync), Candela prompts you for an email address and sends you a magic sign-in code. The address and your synced library state — what fictions you've added, current reading position, voice preferences, settings — are stored in InstantDB, the third-party real-time database Candela uses for sync. Your email is the lookup key for your record. The content of fictions themselves is not synced — only the references (URLs / IDs) and the metadata (position, voice choice).
You can disable sync at any time and your record is deleted from InstantDB on next sync-off. Uninstalling the app also deletes the local cache; the InstantDB record remains until you sign out from another device or contact us to delete it (see Your rights below).
2.2 Fiction backends (your choice, per backend)
Candela connects to the public APIs and websites of the fiction backends you enable. Each is opt-in via Settings → Plugins. The list currently includes: Royal Road, GitHub, RSS, Outline, Memory Palace, Project Gutenberg, AO3, Standard Ebooks, Wikipedia, Wikisource, Radio (Radio Browser API), Notion, Hacker News, arXiv, PLOS, Discord, Telegram, Palace Project, Slack, Matrix, Google Drive, Reddit, and a generic "Readability" catch-all for arbitrary URLs you share into the app.
When you browse one of these backends, Candela sends HTTPS requests to that backend's servers exactly the way a web browser would. Candela does not act as an intermediary — your requests go directly to (for example) royalroad.com from your device. The backend operator sees a normal browser request, with an IP address and possibly a User-Agent header. Candela does not send your email, your sync state, or any identifying token from Candela along with these requests.
For backends that require sign-in (Royal Road follows, AO3 marked-for-later, GitHub OAuth Device Flow, Discord/Slack/Matrix/Telegram bot tokens, Notion integration or OAuth tokens, Google Drive OAuth tokens, Reddit installed-app client id, Azure HD speech key), credentials live on-device and are sent only to that backend's own API. Candela servers (there aren't any beyond the sync database) never see your fiction-backend credentials.
For Google Drive, Candela requests only the narrow drive.file OAuth
scope, which grants access only to files and folders you explicitly pick —
never your whole Drive. Google Docs are read by exporting them to text; other
files are downloaded as you open them. Your Drive content flows directly from
Google to your device. (Opening a single Drive file through Android's system
file picker instead involves no Google credential at all — the OS streams the
file to Candela.)
WebView cookies from AO3 and Royal Road logins are stored in Android's
EncryptedSharedPreferences on your device and never leave it.
2.3 Voice downloads
The first time you pick a voice, Candela downloads it from GitHub Releases
under the voices-v2 tag of the Candela repository (or from the on-device
KittenTTS bundle, which is in-tree). The voice file itself is hosted on
GitHub's CDN; the download request goes directly to
github.com / objects.githubusercontent.com. GitHub can see your IP for
the duration of the download.
After the voice is on-device, all synthesis runs locally. No audio is sent to a server. There are no per-character or per-minute charges.
2.4 Optional cloud TTS (Azure HD, BYOK)
If you provide your own Microsoft Azure Speech key (Settings → Voices → Azure HD), Candela sends synthesis requests directly to Azure's TTS endpoint with the text-to-be-spoken and your key. Candela doesn't proxy, log, or mediate this traffic. Microsoft's privacy policy applies to that request. If you don't add an Azure key, no Azure traffic happens.
2.5 AI chat (BYOK)
The "Chat with this book" feature requires a Large Language Model provider key (OpenAI, Anthropic, Google, etc.). When you ask a question, Candela sends the question + the configured grounding (current sentence / chapter / whole book) directly to the provider's API with your API key. Candela doesn't proxy, log, or charge for this traffic. The provider's privacy policy applies.
2.6 Anthropic Teams sign-in (optional)
Candela supports signing into Anthropic Teams via Chrome Custom Tabs OAuth
for users on an Anthropic Teams plan who'd rather not paste an API key.
Sign-in lands a token in EncryptedSharedPreferences on-device. The token
goes to Anthropic when you chat; nowhere else.
2.7 Call 211 (social services)
The TechEMPOWER Home screen surfaces a single Call 211 shortcut (211 — United Way local community services, US/Canada). Tapping it opens the device's dialer with the number pre-filled — Candela does not place the call automatically, you have to tap "Call" in the dialer. No data about whether you tapped the shortcut is collected or transmitted by Candela. (The earlier 988 and 911 shortcuts were removed in a prior release; 211 is the only remaining dial affordance.)
2.8 Camera / OCR text capture (optional)
Candela can scan printed text with the device camera and turn it into a readable, narratable chapter (optical character recognition). When you start a scan, Candela requests camera permission with a plain-language explanation first, and the camera is active only while you are actively capturing. Text recognition runs entirely on-device via Google ML Kit: the captured image and the recognized text never leave your device and are never uploaded, collected, or shared. Declining the camera permission does not dead-end the feature — you can instead pick an existing image from your gallery, which needs no permission.
2.9 Anonymous impact sharing (optional, off by default)
Candela is run by TechEMPOWER, a nonprofit. The grants that keep the app free need aggregate impact numbers — total hours listened, chapters and books finished, and the range of built-in sources people use — summed across everyone who chooses to help, never any individual. Candela lets you choose to share such a summary, entirely on your terms:
- Nothing is sent automatically, ever. There is no background upload, no scheduled report, and no on/off switch left running. A summary leaves your device only when you open the Listening Stats screen, tap "Preview what will be sent," review the exact contents, and share it yourself through the Android share sheet — to a destination you pick (email, a message, a form). The act of sharing is the consent.
- What a shared summary contains: the current calendar month only; the
app version as
major.minor(e.g.1.9, never the build); coarse, rounded monthly totals (hours and chapters rounded to the nearest 5, books to the nearest 1) of what you finished since your last share; and the set of built-in source IDs you used (names only — e.g.gutenberg,royalroad— never per-source counts, never URLs or titles). You see this exact payload, byte-for-byte, before it ever leaves the device. - What it never contains: no name, email, or account; no device model, OS version, or locale; no IP address; no persistent or rotating identifier of any kind; no timestamps finer than a month; and nothing about what you read (titles, links, contents). The rounding and the "set, not counts" design mean no single summary is precise enough to single out a device.
- Withdrawal. You can simply never share again — nothing further is sent. A summary you already shared lives wherever you sent it; Candela keeps no copy, and because it carries no identifier, TechEMPOWER cannot trace one back to you to remove it. That unlinkability is a privacy strength, but it does mean past contributions can't be individually withdrawn — they were never tied to you.
- Candela keeps a tiny device-local record of the coarse totals you last shared, so a subsequent share reports only the incremental change (never double-counts, and never goes negative if you clear app data). That record holds no identity and is erased when you clear app data or uninstall.
2.10 Calendar (optional)
Candela can read your device calendar and narrate it as an agenda — "My
Calendar," with Today / Tomorrow / This Week chapters (each event's time,
title, location, and duration read aloud). It uses Android's on-device
CalendarContract provider, which already aggregates whatever accounts sync
to your phone (Google, Samsung, Outlook, a local account). There is no
calendar cloud API, no OAuth, and no key — Candela reads the calendar the
same way your built-in Calendar app does, entirely on-device. Your events are
read locally, narrated locally, and never leave your device; they are
never uploaded, collected, transmitted, or shared. The READ_CALENDAR
permission is requested only when you tap Grant calendar access in
Browse — never at launch — and declining it does not dead-end anything: the
Calendar source simply stays empty until you choose to grant it. You can
revoke the permission anytime in Android Settings. The Calendar source is
read-only: Candela never creates, edits, or deletes calendar events.
2.11 Saved household profile (optional)
Candela can save the facts you re-type on every benefits form — name,
address, household size, monthly income, phone, email — so it can offer to
fill them in when you scan a form. This profile is entirely on-device:
it is stored encrypted at rest (Android's EncryptedSharedPreferences),
excluded from cloud backup and device-to-device transfer, and is
never uploaded, collected, transmitted, or shared. It's optional — the
app works without it — and you can view, edit, or permanently delete it at
any time; editing and deleting are protected behind your device lock
(fingerprint / face / PIN).
Your Social Security Number is never saved. It is deliberately not a profile field: when a form asks for it you type it directly, and Candela neither stores it nor offers to fill it — the app actively warns you on any SSN/tax-id field. No network is involved in matching a form field to your saved value; it's all local text comparison.
2.12 Notice deadline reminders (optional)
Candela can photograph a benefits notice (a renewal letter, a recertification form) and set you a local reminder before its deadline. The whole flow is on-device: the photo is read with the same on-device OCR as §2.8 (image and recognized text never leave your device), the deadline date is found by plain on-device text matching (no AI, no network), and you confirm the date before anything is scheduled — Candela never auto-commits a guess.
The reminders themselves are local notifications only. There is no account, no cloud, and no server: the reminder lives on your phone and is delivered by Android at the times you chose (by default one week before, two days before, and on the day). Your reminders are stored in the app's private storage, are excluded from cloud backup and device-to-device transfer, and are never uploaded, collected, or shared. The notification text is yours to edit; by default it shows only a short label plus "deadline" — never dollar amounts or case numbers — so nothing sensitive appears on your lock screen.
Two Android capabilities support this feature, both used only for these
local reminders: notifications (POST_NOTIFICATIONS, which you can grant or deny
and revoke anytime) and exact alarms (SCHEDULE_EXACT_ALARM, so a reminder can
fire at a predictable time on its day). Exact alarms are optional — if you don't
grant them, reminders still fire, just batched by the system — and Candela offers
a one-tap shortcut to the setting rather than nagging. Reminders are re-armed
after a reboot from that same on-device store.
2.13 My Documents wallet (optional, encrypted, device-locked)
Candela can store scans of your benefits paperwork — photo ID, proof of address, gross pay stubs, award letters, benefit cards — in an on-device "My Documents" wallet, so you have your proofs ready when you apply. This is the household's most sensitive data, so it gets the strongest protection in the app:
- Encrypted at rest. Both the document images and their metadata
(type, capture date, your notes) are encrypted with Jetpack Security
EncryptedFile(AES-256-GCM) under a key held in the Android Keystore. Nothing in the wallet is stored in the clear. - Device-credential gate. Opening the wallet requires confirming your
device credential — fingerprint, face, or your screen-lock PIN/pattern —
via Android's built-in secure-unlock prompt
(
KeyguardManager.createConfirmDeviceCredentialIntent). This uses no new permission. Nothing is decrypted until you authenticate. On a device with no screen lock set, the data stays encrypted but opens without a prompt (there is nothing to authenticate against). - On-device only. The images, metadata, and any PDF you export from the wallet never leave your device — no upload, no analytics on contents, no transmission.
- Excluded from backup and transfer. The wallet directory is explicitly excluded from Android cloud backup and device-to-device transfer, and is never part of Candela's optional cloud sync. Your documents do not ride along to another device or to any cloud.
- You control deletion. Delete any document in the app; deleting removes its encrypted files immediately. Clearing app data or uninstalling erases the whole wallet.
The "what does this prove?" hints (which programs accept a given proof) are a built-in, TechEMPOWER-verified reference list bundled with the app; they are static content, involve no lookup, and send nothing off the device.
2.14 Microphone / on-device speech capture (optional)
Two optional features use the device microphone, and both keep the audio on your device:
- Recording mode (#1367) lets you capture your own narration; the recording is saved to your device.
- Voice-paced teleprompter (#1368) listens while you read aloud and scrolls the text to match your voice. It converts speech to text with an on-device recognition model (sherpa-onnx); the audio is transcribed in memory to move the cursor and is not retained.
Candela requests the RECORD_AUDIO permission at runtime — with a plain-language
explanation, and only when you start one of these features, never at launch.
Declining it simply leaves that feature unavailable and dead-ends nothing else.
The captured audio and any on-device transcription never leave your device:
they are never uploaded, collected, or shared. The only related network
request is a one-time download of the on-device recognition model (from the same
GitHub release path as voices, §2.3); after that, recognition runs locally, even
offline. A legacy WRITE_EXTERNAL_STORAGE permission, scoped to Android 9
(API 28) and older (maxSdkVersion="28"), lets recording mode save through the
system media store on those older devices; it is unused on Android 10+.
2.15 Voice Notes (optional)
Voice Notes (#1657) lets you capture a thought, memo, or meeting and turn it
into a searchable note. It uses the microphone (the same runtime RECORD_AUDIO
permission as §2.14, requested only when you start recording), and it is
private by construction — your data stays on your device:
- Recording is on-device. The captured audio is written to app-private storage on your device.
- Transcription is 100% on-device. Speech is converted to text by an on-device model (Whisper); the audio is never uploaded to transcribe it.
- Stored on-device, excluded from backup and transfer. The recording, its
transcript, and the resulting note live in a separate on-device database
(
notes.db). It is excluded from cloud backup and device-to-device transfer, and it is never part of Candela's optional cloud sync — Voice Notes stay only on the device that made them. - The AI summary is opt-in, per note. A note's transcript text is sent to your own configured cloud AI provider (BYOK — Anthropic, OpenAI, or your local Ollama; see §2.5) only when you explicitly tap Summarize on that specific note. Nothing is sent automatically, in the background, or while recording. If no AI provider is configured, or you never tap Summarize, no Voice Notes data leaves your device at all.
No audio ever leaves your device. The only Voice Notes data that can leave
the device is the text transcript of a single note, and only on your explicit
per-note Summarize tap. Uninstalling Candela deletes notes.db and every
recording with it.
3. What we do NOT collect
- No analytics or tracking SDKs. No Firebase, no Google Analytics, no Mixpanel, no Sentry/Bugsnag, no Crashlytics. No fingerprinting, and no per-user usage collection. The one exception is the opt-in Anonymous impact sharing feature (off by default, see §2.9), which — only if you choose to use it — lets you share coarse, rounded, unlinkable monthly totals with TechEMPOWER, with no identifier of any kind. Candela still sends nothing on its own.
- No advertising. No ad SDKs. No ad IDs requested. The
com.google.android.gms.permission.AD_IDpermission is not declared in the manifest. - No tracking pixels. No third-party JavaScript loaded into the reader.
- No location data. Candela never asks for location permission.
- No audio is collected or transmitted. Candela does use the microphone for optional, on-device features — recording mode and the voice-paced teleprompter's speech-to-text (§2.14), and Voice Notes (§2.15) — but the captured audio is processed entirely on your device and never leaves it: it is never uploaded, collected, or shared. Voice Notes are also transcribed on-device; the only data that can ever leave is the text transcript of a single note, and only on your explicit per-note Summarize tap to your own BYOK AI provider (§2.15). (The TTS engine also generates its audio locally; that, too, is never sent anywhere.)
- No contacts access. Candela never reads your contact book.
- No background data collection. When the app isn't running, it isn't doing anything (with one exception: the now-playing widget reads its own cached state to render; no network is performed by the widget).
4. Third-party services
Candela connects directly to these third parties only when you opt into a feature that uses them. We don't share any data with them; you communicate with their servers from your device, the same way a web browser would.
| Service | When | What's sent | Their privacy policy |
|---|---|---|---|
| InstantDB | Sync enabled | Your email, your library state | instantdb.com/privacy |
| GitHub | Voice download, GitHub source, voice catalog fetch | HTTP request (IP visible) | GitHub privacy |
| Royal Road / AO3 / etc. | When you browse those backends | Your browser-like request | Their respective policies |
| Microsoft Azure | Only if you add an Azure key | Text-to-speak + your key | Microsoft Privacy Statement |
| OpenAI / Anthropic / Google AI | Only if you add an LLM key | Your chat messages + your key | Their respective policies |
| Notion | Only if you add a Notion token | Notion API requests | Notion privacy |
| Google Drive | Only if you connect Google Drive (drive.file scope) |
Drive API requests for files you grant | Google privacy |
| Discord / Slack / Telegram / Matrix | Only with explicit token / homeserver setup | Bot-token API calls | Their respective policies |
| Only if you add a Reddit client id | OAuth API requests (read-only) | Reddit privacy | |
| Radio Browser API | Radio backend enabled (default off) | Station search queries | radio-browser.info |
| Palace Project (libraries) | Palace backend enabled | OPDS catalog queries | thepalaceproject.org/privacy |
Anonymous impact sharing (§2.9) adds no service to this table: Candela does not operate a collector and connects to no endpoint for it. When you choose to share a summary, Candela hands the text to whatever app you select in the Android share sheet (your email client, a messaging app, a web form); that app — your choice, using your own account — delivers it. Candela itself transmits nothing and involves no third party in the act.
We do not sell, share, or rent your data. We don't have your data to sell — it's on your device.
5. Data retention
- On-device data (library, settings, voice files, WebView cookies, BYOK tokens, AI chat history) lives in Candela's private app storage. It persists until you uninstall the app or clear app data from Android Settings. Uninstalling deletes everything.
- Synced data (only if sync is enabled) lives in InstantDB until you explicitly delete it. Use the in-app "Delete cloud data" action to purge synced data from InstantDB. Signing out of sync revokes your auth token and wipes local session data, but does not delete the cloud record.
- Voice downloads stay in Candela's cache until you delete them (Settings → Voices → Manage → Delete).
6. Children's privacy (COPPA)
Candela is built to be accessible — among other things, that means it has to work for users who can't or don't want to navigate complex interfaces, including older children. We do not knowingly collect any personal information from children under 13.
- The default install collects nothing, period.
- The sync feature requires an email address; we don't verify age, but children under 13 in the US (and under the analogous local age elsewhere) should not enable sync without parental consent per applicable law.
- Fiction backends may surface content not suitable for children. Candela does not filter or moderate backend content — that's up to the backend operator. Parents managing the app for a child user should disable backends with unfiltered user-generated content (Royal Road, AO3, Discord, Slack, the magic-link Readability catch-all).
If you believe a child under 13 has provided Candela with personal information via the sync feature, contact us (see Your rights) and we'll delete the record.
7. Security
- On-device encryption. Sensitive credentials (WebView cookies, BYOK
API keys, Anthropic Teams OAuth tokens) are stored in Android's
EncryptedSharedPreferences, which encrypts at rest with a per-app key bound to the device. The My Documents wallet (§2.13) goes further: document images and metadata are stored asEncryptedFile(AES-256-GCM under an Android Keystore master key), gated behind a device-credential (fingerprint / face / screen-lock) prompt, and excluded from cloud backup and device transfer. - HTTPS everywhere. All network requests use HTTPS. The app's
network_security_config.xmlenforces this — cleartext HTTP is rejected by the platform. - No analytics surface to compromise. We don't ship analytics SDKs, which means there's no analytics endpoint that could be compromised to exfiltrate user data.
- Open source. Anyone can audit Candela's network behavior at github.com/techempower-org/candela. If you spot a privacy bug, file an issue or email us.
8. Your rights
You have the right to:
- Know what's stored. Everything is either on your device (you can inspect via Android's Settings → Apps → Candela → Storage) or in your InstantDB sync record (you can view via the sync settings screen).
- Delete your data. Uninstall the app to delete on-device data; sign out of sync to delete the InstantDB record.
- Export your data. Per-fiction EPUB and chaptered
.m4baudiobook export shipped in the v1.x line; contact us if you need a full export of your account data. - Contact us with privacy questions at the contact address listed at the top of this document.
If you're a resident of California (CCPA), the EU (GDPR), or another jurisdiction with applicable data-protection law, you have additional rights including the right to request access, correction, or deletion of your personal data. Contact us and we'll honor those requests within the statutory timeframe.
9. Changes to this policy
We'll post material changes to this page with an updated "Effective date"
above. The previous versions are visible in the git history at
docs/privacy.md in the Candela repository — the policy itself is
versioned alongside the app.
For substantive changes (new third-party service, new data collected, etc.) we'll mention the change in the Play Store release notes for the version that introduces the change, and surface a one-time notice in-app.
10. Contact
For questions, requests, or concerns about your privacy in Candela:
- Email:
jp@jphein.com - GitHub issues: github.com/techempower-org/candela/issues (public; do not include private information)
Candela is operated by TechEMPOWER, a 501(c)(3) nonprofit. The app is licensed under the GNU General Public License v3.0.