Privacy Policy

Privacy comes first in Lector. The self-hosted app keeps everything on your own hardware. This website asks for your email address in two places. Here is the full picture.

Short version. If you host Lector yourself, we see nothing. Your reading, vocabulary, and progress never leave your server. This site uses analytics that set no cookies.

Two forms ask for your email address. The language interest list sends one announcement. The contact form sends your message to us. We use that message to reply. The cloud service will store only what the account needs. Paddle handles payments.

Pulling the container image from our address counts the pull. We store no IP address for it, and you can pull from ghcr.io instead to stay out of the count.

The self-hosted app

When you run Lector on your own hardware, we collect nothing. Your books, vocabulary, cloze history, journal entries, and settings live in a SQLite file on your server. We have no access to it, no telemetry, and no accounts. Any translation or AI features you enable talk directly from your server to the provider you configure (the Claude API, or a local model) using your own keys — not through us.

Pulling the container image

Lector ships as a container image. The default install pulls it from registry.lector.dev, which is our own address in front of GitHub's registry. We run it for one reason: GitHub publishes no pull statistics, so without it we have no idea how many people run Lector.

When you pull, we record the tag you asked for, the image version it resolved to, your container client (Docker, Podman, and so on), your country code, and the Cloudflare location that served you. We do not store your IP address — not in those records, and not anywhere else. Our diagnostic logs capture errors so we can fix them; they do not record who pulled. Cloudflare handles the connection itself, as it does for the rest of this site.

To count installs rather than pulls, we need to tell two pulls apart without knowing who either came from. So your address and client are hashed together with a random salt that we throw away every day, the same approach Plausible uses for this site. The salt is deleted after 48 hours. Once it is gone, the hashes it produced cannot be traced back to an address by anyone, including us, and the same person cannot be recognised from one day to the next. The code that does this is public — see the dailySalt and pullerId functions.

The numbers we get out of this are rough on purpose: a count of pulls, a count of distinct pullers per day, and a breakdown by version and country. Nothing about your server, your books, or your reading is involved — that never leaves your hardware.

If you would rather not be counted. Pull the same image straight from GitHub instead. It is the identical image, and the request never touches us:

docker pull ghcr.io/heuwels/lector:latest

It is a drop-in swap: change the image line in your docker-compose.yml and nothing else about the install differs.

This website

We use Plausible, a privacy-friendly analytics tool, to understand aggregate traffic (page views, referrers, rough country). It sets no cookies, collects no personal data, and doesn't track you across sites. We don't run advertising or third-party trackers.

The language interest list

The reference data page and the roadmap carry one form. It asks which language you want and where to reach you. We store your email address, the language, your optional note, your country code, and the user agent string from your browser. We do not store your IP address.

That address has one purpose. We will email you once, on the day the language you asked for is ready. It is not a newsletter, and we never sell it or pass it to another company. Counts of people per language appear in public on those pages. Individual addresses never do.

To come off the list, email [email protected] and we remove you. The form uses Cloudflare Turnstile to block bots. Turnstile sets no cookies that track you, and it does not profile you across sites.

The contact form

The contact page has a form. The form asks for your name, your email address, a topic, and your message.

We send that message to [email protected]. Resend delivers the email. We do not keep a copy on this site. Resend keeps the email as part of delivery. We use your address only to reply. The message that we receive also includes your country code and the user agent string from your browser.

To block bots, the form uses Cloudflare Turnstile. Turnstile sets no cookies that track you, and it does not profile you across sites.

The cloud service

The managed cloud service isn't available yet. When it launches, it will collect only what's needed to provide it:

  • Account. Your email address and authentication details, so you can sign in and we can contact you about your account.
  • Billing. Payments are processed by Paddle, our merchant of record. Paddle handles your payment details under its own privacy policywe never see or store your card number. We receive only your subscription status and plan.
  • Your content. Text you import or translate is stored to provide the service and may be sent to a translation provider (e.g. the Claude API) to return results. If you enable bring-your-own-key, that processing uses your keys. We don't use your content to train models and we don't sell it.

Your rights

You can request access to, export of, or deletion of your data at any time. If you cancel, your data is retained so you can export it or renew, and is deleted on request. Depending on where you live, you may have additional rights under laws such as the GDPR or the Australian Privacy Principles — we'll honour them.

Contact

Privacy questions or requests? Email [email protected]. You can also use the contact page. Lector is operated by Luke Boyle.

What changed

Every version of this policy appears below, with the newest at the top. We update this page when the policy changes. We do not email you about a change, because we keep no general mailing list.

Version 4 —

  • Added a section about pulling the container image. The image can now be pulled from registry.lector.dev, which counts pulls so we know roughly how many installs exist.
  • Explained the daily rotating salt that stands in for an IP address, and linked the code that does it.
  • Named ghcr.io as the way to pull the image without being counted.

Version 3 —

  • Added a section about the contact form. The site now asks for your name, email address, and message on the contact page.
  • Named Resend as the service that delivers contact emails.
  • Corrected the summary. Two forms now ask for an email address.

Version 2 —

  • Added a section about the language interest list. The site now asks for your email address on the reference data page and on the roadmap.
  • Corrected the summary. It said that this website collects no personal data. The language interest list made that statement wrong.
  • Named Cloudflare Turnstile as the bot check on that form.

Version 1 —

  • The first published policy.