Privacy Policy

This policy describes what data vocapi (operated by Johnathan Jay Oneal) collects, why we collect it, and the choices you have. It applies to the vocapi mobile application and this website.

We are not in the business of selling your data, and we do not show advertising. We collect only what we need to make the product work and understand where the experience is confusing or failing.

The short version

What we collect

Account identity

When you sign in with Google or Apple, we receive a unique identifier issued by that provider (an opaque user ID) and an email address, which Supabase Auth stores with your auth account. With Apple Sign In, that email may be a private relay address. Google or Apple may also provide a profile name; it can initialize your public display name, which you can edit.

Learning data

You create this data by using the app:

Profile photos (only if you add one)

You can choose an image from your photo library, take one with your camera, or explicitly choose the photo supplied by Google Sign-In. We access only the image you choose or take. The original is processed in memory: we correct orientation, crop it to a square, resize it, remove embedded metadata, and encode a normalized WebP. We do not store the original file.

We store the normalized image in a private Supabase Storage bucket and send those exact same normalized bytes to Google Cloud Vision SafeSearch solely to check whether the photo is suitable for a social profile. Google returns category likelihoods; it does not decide your account status. Clearly acceptable photos can be approved, clearly unsuitable photos can be rejected, and ambiguous results can be reviewed by an authorized vocapi operator. A pending or rejected photo is not shown to other members. If you already have an approved photo, it remains in place while a replacement is checked.

An approved photo can be seen by you and by another signed-in member only when both of you have joined the community, you have a pending or accepted friend relationship, and neither has blocked the other. The storage bucket itself is not public. If someone reports an offensive profile, we preserve the exact private photo version that was visible when the report was filed so an authorized operator reviews the right evidence, even if the profile owner later changes or removes it.

Shared learner profiles

After joining the community, you can choose which enrolled languages and up to three earned achievements appear on your learner profile. You can separately allow accepted friends to see your current streak and total days practiced. Pending requests and shared-link visitors never receive those habit details.

Public profile links start off. If you enable one, anyone who has its unlisted link can see your display name, initials, member-since date, and the language progress and achievements you selected. The link does not include your profile photo, account identifier, friendship state, or practice habit. You can disable it or create a new link at any time. A profile image you export contains the same limited information and remains on your device until you choose an app through the system share sheet.

Subscription state

If you purchase a subscription, the App Store or Google Play handles your payment. We receive your transaction ID, subscription tier, expiry dates, and billing event timestamps via RevenueCat, our subscription manager. We never see your card number, billing address, or any other payment information.

Push notification tokens (only if you opt in)

If you allow notifications, we store the Expo push token issued by your device so we can send the daily reminder you chose. The token is opaque (it does not identify you outside of our database).

Product analytics events (only while analytics is on)

We record a small number of named events to understand how onboarding and the first learning session go. These events do not contain anything you typed or any sensitive content. Example events: signup_completed, language_picked, daily_goal_set, first_lesson_completed. Each event is tagged with your opaque account identifier, which is the same stable ID we use to recognize you across devices and not a fresh per-session value. Each event also carries platform metadata (operating system, app version). This is identified product analytics rather than anonymous analytics.

Whether analytics starts on or off depends on where you are when you create your account: if you are in the European Economic Area or the United Kingdom, it starts off and only runs if you turn it on; everywhere else it starts on and you can turn it off at any time. Either way, the Product analytics control in Settings takes effect immediately and is honored on both the client and our servers.

Diagnostic and crash data

To find and fix bugs we use Sentry, which captures unhandled errors with a stack trace, the screen or endpoint where the error occurred, navigation breadcrumbs, and your account identifier. When an error occurs, the mobile app is also configured to send Sentry a replay of the interactions leading up to that error, with all on-screen text and images masked so it cannot capture what you typed or your answers. Routine sessions are not sampled for replay.

Authentication metadata

Supabase Auth (our authentication provider) stores the IP address and user-agent of your most recent sign-in, used to detect compromised sessions. We do not log or store IP addresses elsewhere in the application.

Approximate country (at sign-up)

When you first sign in, our network provider (Cloudflare) derives an approximate country from your IP address. We use this country code once, solely to set your analytics consent default correctly for your region (see above), and we do not store your IP address or use this for any other purpose.

What we do not collect

Third parties we share data with

We only share data with the providers we need to run the service. Each is listed below with what it receives and why.

Service Purpose Data received
Supabase Authentication, database, and file storage Account identity, all learning data, private normalized profile photos if added, and audio files (no personal data in audio)
Google Cloud Vision Profile-photo safety check The exact normalized profile-photo bytes, with embedded metadata removed; no vocapi user ID, display name, or email address
Sentry Error tracking and diagnostics Account identifier, stack traces, navigation breadcrumbs, performance data, and an interaction replay when an error occurs
PostHog (optional) Optional product analytics Account identifier, named events, and platform metadata. Off when you opt out.
RevenueCat Subscription state, App Store / Google Play receipts Account identifier, transaction IDs, subscription tier and dates
Expo Push notification delivery Push tokens (issued by your device, do not identify you elsewhere)
Google / Apple Sign-in providers Provider account ID, email address, an optional profile name, and an optional Google profile-photo URL; vocapi retrieves the image at that URL only if you explicitly choose to import it

All of these services are bound by their own privacy policies and may process data in the United States or other countries where they operate. We do not use any of them to advertise to you.

How long we keep your data

Your rights and choices

Access, export, and deletion

You can delete your account at any time from the app's Settings screen. Deletion is immediate and first removes every private profile-photo object, then removes your auth account and every database record tied to your user ID, including reports and retained photo evidence. If private-object cleanup cannot complete, deletion stops and reports an error rather than leaving photos behind without their ownership records. Some diagnostic and payment-provider records follow the separate retention periods above. If you would like a copy of your data before deletion, contact us at the email below and we will export it for you.

Turn analytics on or off

In Settings, use the Product analytics toggle. Enabled events are associated with your opaque account identifier, so this is identified product analytics rather than anonymous analytics. The control takes effect immediately on your device and is honored by our servers. If you are in the EEA or UK it starts off until you turn it on; everywhere else you can turn it off at any time.

Notifications

You can change your reminder time, turn notifications off, or revoke the OS-level permission at any time from your device's settings or from the app.

Profile sharing

Profile sharing controls are available in the app. Turning off a public link makes that link unavailable; creating a new link invalidates the old one. You can also hide every selected language, achievement, or friend-only habit without deleting the underlying learning data. Deleting your account removes the profile-sharing settings and invalidates its link.

Photos and camera

You can deny or revoke photo-library or camera permission in your device settings. The app will continue to work with initials instead of a profile photo. Removing a profile photo stops displaying it; a reported version may remain private as evidence until the report or account is deleted, as described above.

If you live in the European Economic Area, the United Kingdom, Switzerland, or California

You have additional rights under GDPR, UK GDPR, and CCPA, including the right to access, correct, restrict, or port your personal data, and the right to object to certain processing. Email us at privacy@vocapi.app and we will respond within the legally required window (30 days for GDPR, 45 days for CCPA).

Children

vocapi is not directed at children under 13 (under 16 in the EU). We do not knowingly collect personal data from children. If you believe a child has provided us with their information, please contact us and we will delete it.

Security

Authentication tokens are encrypted at rest on your device using your platform's secure storage (Keychain on iOS, EncryptedSharedPreferences on Android). All network traffic between the app and our backend uses HTTPS. Our database enforces row-level security so one user cannot read another's data, even in the event of a bug in our application code. Profile-photo objects are private and are served only after the backend rechecks the viewer, relationship, community-consent, block, version, and approval state.

Changes to this policy

If we materially change how we handle your data, we will update this page, change the "Last updated" date at the top, and notify you in-app before the change takes effect.

Contact

Johnathan Jay Oneal
Privacy questions: privacy@vocapi.app
General support: vocapi.app/support