Privacy Policy
Effective date: 28 May 2026 Last updated: 1 October 2026
This policy explains what data LingoDrive collects, why, who it goes to, and what your rights are under the EU General Data Protection Regulation (GDPR).
It is written to be accurate, not to sound nice. If something here is unclear or you spot a contradiction with how the app behaves, please email support@kedigital.dev.
1. Who is responsible (the controller)
LingoDrive is operated by Koray Elbek (independent developer, Copenhagen, Denmark). For privacy questions, data access requests, or deletion requests, contact support@kedigital.dev.
We do not yet have a formal Data Protection Officer. For solo-developer-scale processing this is permitted under GDPR Art. 37 — that may change as the user base grows.
2. What data we collect, and why
The plain-English version: we need your voice to do speech-to-text, your email to let you sign in, and a device identifier so anonymous users can have a usage quota. That’s the whole list. We don’t collect your name, your contacts, your location, your photos, or your browsing.
2.1 Audio (your voice)
- What: raw microphone audio (16 kHz mono WAV) for the sentence you’re speaking during a practice session.
- Why: to transcribe what you said so the app can score it.
- Where it goes: captured on your phone → sent over HTTPS to the LingoDrive backend → forwarded to OpenAI Whisper (US-based speech-to-text provider).
- Retention: not stored. The backend streams your audio to OpenAI and discards the bytes after the response comes back. It is not saved to disk, the database, or any log file on our infrastructure. OpenAI’s own retention of API data is governed by their privacy policy.
2.2 Account data (only if you sign in)
If you create an account, we store:
- Email address (lower-cased, used as your unique identifier).
- Password, hashed with ASP.NET Core’s
PasswordHasher<User>(PBKDF2). We never see your plaintext password. - Google account identifier (sub), only if you sign in with Google instead of email/password — used to recognise you on next login. No name, no photo, no contacts.
- Language preferences (native language code, target language code, level).
- Pro subscription status (
IsPro,ProUntil) — flags only, no card details. See §7.
We do not store your name, phone number, profile photo, IP address column, or any other personal identifier.
2.3 Anonymous device identifier
If you use LingoDrive without signing in, we need a way to count the free practice exchanges and podcast episodes you’ve used, so the free tier can have limits that a reinstall doesn’t reset.
To do that the app reads your phone’s Android ID (Settings.Secure.ANDROID_ID) and sends it to our backend once. We do not store it. The backend immediately runs it through a keyed one-way hash (HMAC-SHA256, with a secret only we hold) and stores only the 32-character result. This derived identifier:
- Lets us count how many free practice exchanges and podcast episodes have been used on this device.
- Is pseudonymous and one-way — it cannot be turned back into your Android ID, and it carries no email, name, or device fingerprint.
- Is not your advertising ID, and is never shared with anyone or used for advertising, profiling, or tracking you across apps.
- Android scopes the Android ID itself to the app’s signing key, your device and your user profile, so it is not a value other developers’ apps can see.
It deliberately survives uninstall, reinstall and “clear data.” That is the whole point: without it, anyone could reset their free allowance by reinstalling. This is the one piece of data that is not erased when you delete your account — see §2.7 and §5.
2.3a The device ledger (abuse prevention)
Against that derived identifier we keep a single row holding:
- The number of free practice exchanges used on this device.
- The number of free podcast episodes started on this device.
- Whether an account has ever been created on this device (so the one-time new-account bonus can’t be claimed repeatedly).
- When the device was first seen, and when the row was last touched.
It holds no other data about you. We keep it under our legitimate interest in preventing fraud and abuse of the free tier (GDPR Art. 6(1)(f), Recital 47), and it is storage-limited: a row untouched for 365 days is deleted automatically, and is ignored for quota purposes in the meantime. If you want this row removed sooner, email us (§6) — but note that doing so resets your device’s free allowance, so we may ask you to confirm that’s what you intend.
2.4 Practice usage data
For each completed practice exchange we record one row containing:
- Your user UUID (if signed in) or device UUID (if anonymous).
- A timestamp (UTC).
- The session ID.
- The kind of exchange (e.g. “answered”, “asked for help”).
We do not store the text you spoke, the AI’s reply, or any transcript. Those exist only in memory on the backend during your session and are evicted 30 minutes after your last interaction.
2.5 Conversation transcripts (in-memory only)
While a practice session is active, the backend keeps the recent dialogue in memory so the AI can respond in context. This data:
- Lives in RAM on the server.
- Is evicted 30 minutes after you stop interacting.
- Is not persisted to a database or log.
- Is sent to OpenAI (US) as part of the LLM prompt during the session — see §3.
2.6 Crash reports
If the app crashes, it sends a report containing:
- The exception message and stack trace.
- Your Android OS version and locale (e.g. “Android 14 / da-DK”).
- App version.
- Anonymous device ID (so we can correlate repeated crashes from the same install).
These reports go to our own backend — no third-party crash service (no Sentry, no Firebase Crashlytics, etc.). Reports are logged plaintext to our hosting provider’s log stream (see §3 for hosting). Stack traces can incidentally contain file paths or in-memory values; we keep them only as long as our hosting provider’s log retention allows (currently ~30 days).
2.7 What we don’t collect
For clarity:
- No location. No
ACCESS_FINE_LOCATIONorACCESS_COARSE_LOCATIONpermission, in the app or in the car. The “mic opens automatically” setting is a UI preference for when the microphone opens; no GPS or positioning is used. - No analytics SDKs. No Google Analytics, Firebase, App Center, Sentry, AppsFlyer, or anything similar.
- No advertising identifiers. We never read the Google Advertising ID. The device identifier in §2.3 is a one-way hash used only for free-tier limits, never for advertising.
- No contacts, calendar, SMS, or call log access.
- No background data collection. The app only captures audio while you’re in an active practice session and are holding/triggering the mic. The microphone is never opened in the car — Android Auto playback is listen-only.
3. Third parties (sub-processors)
Your data is sent to the following parties only to operate the service:
| Sub-processor | Role | Data sent | Region |
|---|---|---|---|
| Microsoft Corporation (Azure AI Speech) | Text-to-speech (only sentences the AI says, no personal text) | Plain text strings | Region of the configured Azure Speech resource |
| OpenAI, L.L.C. | Conversation LLM (default gpt-4o-mini); speech-to-text (Whisper) |
Practice conversation history (your transcribed speech, AI replies, your level, your language pair); audio bytes (STT) | United States |
| Google LLC | Sign-In identity verification only (if you choose Google sign-in) | Your Google ID token (verified server-side); after verification we keep only your Google sub claim |
United States |
| Railway Corp. | Backend hosting + managed Postgres + log storage | All data described in §2 that is persisted server-side | Region not pinned; assume United States |
| Visiana ApS / GitLab Inc. | Source code hosting (CI/CD) | No end-user data | EU / United States |
Cross-border transfers. Microsoft, OpenAI, Google, and Railway are US-based. Transfers from the EU to the US rely on the EU-US Data Privacy Framework where the provider is certified, or on Standard Contractual Clauses (SCCs) per GDPR Art. 46.
4. Legal bases (GDPR Art. 6)
- Audio processing, account data, usage data: contractual necessity (Art. 6(1)(b)) — we cannot provide the practice service without it.
- Crash reports: legitimate interest (Art. 6(1)(f)) — we need to know when the app is broken. Balanced against the minimal personal data involved (anonymous device ID + stack trace).
- Authentication via Google: consent (Art. 6(1)(a)) — you explicitly chose this sign-in path.
5. How long we keep it
| Data | Retention |
|---|---|
| Account row (email, password hash, language prefs, etc.) | Until you ask us to delete it (see §6). LingoDrive does not auto-purge accounts. |
| Usage records (one row per exchange) | Until you delete your account; then deleted with it. |
| Podcast play history (which episodes this account/device has heard) | Until you delete your account or clear your practice data; then deleted with it. |
| Device ledger (hashed device ID + free-tier counters, §2.3a) | Survives account deletion and “clear data” by design. Purged automatically 365 days after the device was last active. |
| Conversation transcripts | In-memory only; 30 minutes after your last activity. |
| TTS audio | In-memory cache, evicted on a 1024-entry LRU policy. |
| Captured audio (your voice) | Not retained. Streamed through and discarded. |
| Crash reports | Up to 30 days in hosting provider logs. |
6. Your rights
Under GDPR you have the right to:
- Access the personal data we hold about you.
- Rectify anything inaccurate.
- Erase your data (“right to be forgotten”).
- Restrict or object to processing.
- Data portability (receive your data in a machine-readable format).
- Lodge a complaint with your national data protection authority — in Denmark, that’s Datatilsynet.
How to exercise these rights today:
- Access / data portability: open Settings → Privacy → Download my data in the app. You’ll get a JSON file containing your account row and every practice-usage record we hold for you. The file lands in
Android/data/<package>/files/Download/and is browsable from the system Files app. - Erasure (right to be forgotten): open Settings → Privacy → Delete my account in the app. A two-step confirmation prevents accidents. On confirmation we delete the user row and every associated usage row immediately and irreversibly, and sign you out. The one thing this does not delete is the hashed device ledger row described in §2.3a — it holds no account data, and removing it would defeat the free-tier abuse protection it exists for. Email us if you need that row removed too.
- Anonymous users: if you’ve never created an account, Settings → Privacy → Clear my practice data purges every usage row attached to your device’s anonymous identifier.
- Anything else (rectification, restriction, complaints we can’t resolve in-app): email support@kedigital.dev with your account email. We aim to respond within 30 days.
7. Payments
Not yet implemented. The “Upgrade to Pro” screen exists but takes no payment today. When billing is added it will go through Google Play Billing (we will never see your card details — Google handles that entirely). This policy will be updated and you will be notified before any payment processing begins.
8. Children
LingoDrive is not directed at children under 13 (or under 16, depending on jurisdiction). We do not knowingly collect data from children. If you believe a child has created an account, contact us and we’ll delete it.
9. Security
- All client-server communication uses HTTPS (TLS).
- Passwords are stored as PBKDF2-hashed values, never plaintext.
- Authentication tokens are signed HS256 JWTs with 365-day lifetime for device tokens and shorter lifetimes for authenticated sessions.
- The backend is hosted on Railway, which provides infrastructure-level security; we layer application-level access controls on top.
No system is unbreakable. If we detect a breach affecting your personal data we will notify you and the relevant supervisory authority within 72 hours per GDPR Art. 33–34.
10. Changes to this policy
When we update this policy materially (e.g. adding a new sub-processor, changing what data we collect), we will:
- Update the “Last updated” date at the top.
- For signed-in users, surface a notice in-app on next launch.
- For significant changes, ask you to re-consent before continuing to use the service.
The change history of this document is publicly visible in the LingoDrive Git repository.
11. Contact
Koray Elbek support@kedigital.dev Copenhagen, Denmark
For privacy-specific questions, use the same email and put “Privacy” in the subject line.