Privacy policy

Last updated: 2026-09-20

Summary

Reading reactions needs no account and no sign-in. To show a count, the extension asks our server for the public identifier of each supported item that scrolls into view; that lookup carries no account, no installation identifier, and no cookie, and the server neither stores nor logs which identifiers were asked for. To submit your own reaction you sign in once through a provider you already use (Google, Apple, Microsoft or Twitch); the request asks the provider for the standard openid scope only, so no name, email or picture reaches us. Only a one-way keyed hash of the opaque id the provider assigns you, plus the provider's name, is persisted as your account record. You can delete that record at any time from the extension settings.

Website analytics and extension reaction context. On emojery.app, the marketing site you are reading right now, we use 2 complementary analytics layers: Google Analytics (loaded through Google Tag Manager, cookie-based, consent-gated in the EEA, the UK and Switzerland, on by default elsewhere) and Cloudflare Web Analytics (cookieless, aggregated traffic counts only, no user identifiers). Decline the cookie banner and the site works exactly the same. The browser extension itself does not load Google Analytics, Cloudflare Web Analytics, or any other analytics SDK. Active reaction rows keep timestamps and an active-row count of reaction changes. Each reaction submission includes the current "Community insights" setting value. When that setting is enabled (default; you can opt out in extension settings), reaction submissions also carry context for aggregate maps: country and city, language, browser family, and operating system.

For what the extension can technically access in your browser, and why each permission exists, see Browser permissions.

What we collect

What we do not collect

Website analytics and cookies

Where this applies: only the marketing website emojery.app. The browser extension itself does not load Google Analytics, Google Tag Manager, or any analytics SDK. Extension reaction context is first-party data sent only with reaction submissions, controlled by the extension setting described above.

We use Google Tag Manager to load Google Analytics 4 on the website. We use it to understand how many people land on the install page, which articles get read, which referrers send the most traffic, and a country-level breakdown of visitors. We do not run ads, we do not use Google Signals (cross-device audiences), and we do not run remarketing.

Whether the cookies are set depends on where your browser says you are. The site reads the time zone your browser reports and treats a European, UK or Swiss zone as a visit from the EEA, the UK or Switzerland. For those visits, Google Consent Mode v2 keeps every storage type denied until you click Accept on the consent banner: page views are counted in an anonymized, cookieless mode and the request identifier is reset every 24 hours, and if you decline, that mode persists for the rest of the session. For every other visit the banner is not shown and the analytics cookies are set on the first page view; there is no in-page switch to refuse them, and the ways to opt out are listed in the cookie policy.

For the full cookie inventory (names, lifetimes, providers, and the cookieless layer) see the dedicated cookie policy. In short: 2 first-party GA4 cookies (_ga and a _ga_* per-property one), plus 3 localStorage keys that hold choices you made on this site: your banner decision (emojery-consent-v1), your theme (theme), and your roadmap upvotes (em_roadmap_liked).

To change your decision later, clear your browser's cookies and localStorage for emojery.app — the consent banner will reappear on next visit. The cookie policy has step-by-step instructions.

Cloudflare Web Analytics (cookieless)

In addition to Google Analytics, we also use Cloudflare Web Analytics, which runs alongside GA but works completely differently. It is cookieless, sets no localStorage, does not assign user identifiers, and produces only aggregated, anonymous traffic numbers (visits, top pages, referrer source, country, browser).

Because no information is stored on your device by Cloudflare Web Analytics, it is not gated behind the cookie banner. It processes server-side aggregates under our legitimate interest (Art. 6(1)(f) GDPR) in keeping the site healthy and understanding its traffic. There is nothing to opt out of at the cookie level because nothing is set on your device. If you would prefer that we exclude your visits entirely, a browser-level "Do Not Track" or a Cloudflare-blocking extension (uBlock, AdGuard, Privacy Badger) will hide your visit from this layer as well.

Where data lives

How long we keep it

One row per thing we hold. Where a row says "immediately", it means the delete runs inside the request you triggered rather than on a nightly job.

What How long it is kept Where it lives
One-time sign-in code 10 minutes, or until you use it — whichever comes first. Ephemeral edge storage
Session token 30 days, then it stops working and you sign in again. Signing out drops it at once. Your browser's extension storage
Replay-protection tokens, rate-limit counters, the state of a sign-in in progress Each expires on its own timer, measured in minutes to hours. The exact windows are not published — see below. Ephemeral edge storage
Your account record — the one-way keyed hash of your provider's opaque id and the provider's name, plus the hashed installation identifier and the daily session identifier derived from it Until you delete the account, which you can do yourself from the popup's Account tab. Deletion is immediate. Managed database (EU or US region)
An active reaction — the target, the emoji, the row timestamps, the count of changes, and the country, city, language, browser and OS context if you left “Community insights” on For as long as that reaction stands. Removing the reaction, or deleting the account, removes the record immediately. Managed database (EU or US region)
Aggregate counts per target Indefinitely — they are the numbers the extension displays. Your contribution to them is decremented the moment you remove a reaction or delete the account. Managed database (EU or US region)
Entries in the public transparency log, under a rotating pseudonym Permanent by design. Deletion appends a public revocation that reverses the entry; it cannot erase it, and neither can we. Public log repository, mirrored by third parties
A bug report you sent from the Report tab — the page address, your note, and the user-agent string and version if you left “Community insights” on, filed under your internal account identifier Until removed by hand. There is no automatic sweep, and deleting your account does not delete it: the identifier it carries then points at no account, but the address and the note stay. Removed on request. Managed database (EU or US region)
The installation ledger — first-seen and last-seen times keyed by the hashed installation identifier alone 90 days after the installation was last seen. Not linked to an account and not touched by account deletion. Managed database (EU or US region)
Roadmap upvote marker — a fixed salted hash of your IP address next to each roadmap entry you upvoted on this website 365 days. Managed database (EU or US region)
Uninstall-survey answer, and the email address only if you left one Until removed by hand, which happens once it has been read and, where you asked for a reply, answered. There is no automatic sweep. Removed earlier on request. Managed database (EU or US region)
API-waitlist address Until the single launch announcement is sent, after which the waitlist is deleted by hand. Removed earlier on request. Managed database (EU or US region)
The provider-id hash of an account terminated for abuse Kept after deletion, without an end date, for the single purpose of enforcing the termination — see Your rights. Managed database (EU or US region)
Live anti-abuse counters derived from the hashed identifiers above (how many accounts one installation has signed in, how many reacted to one target from one network in a day, and the like) Each row expires on its own timer and is swept on a schedule. The windows are not published — see below. Deleting your account removes your rows at once. Managed database (EU or US region)
Abuse decisions about individual reactions — internal account identifier, target, emoji, network number, and the signals that fired 90 days from the decision. Kept after account deletion. Managed database (EU or US region)
Reviews of linked accounts — the account identifiers and targets of accounts that share an installation or vote in lockstep, and the operator's note on the case While the review is open, and 90 days after it is closed. Kept after account deletion. Managed database (EU or US region)

The windows we do not publish

One family of period in the table above is stated as a criterion instead of a number: how long the rate-limit, lockout, replay and live anti-abuse windows run. Publishing them would be publishing the waiting time — the exact interval to sit out between attempts in order to stay under a limit that exists to keep automated voting off the counters. That is an abuse manual rather than a privacy disclosure, and the people it helps are not the ones this page is written for.

What we will commit to instead: every such window is bounded, each is enforced by an expiry the record carries with it rather than by anyone remembering to delete it, none is exempt from anything else on this page, and a supervisory authority or a court asking for the actual figures gets them. The 2 records that do outlive an account, abuse decisions and reviews of linked accounts, carry the fixed periods stated in the table.

Subprocessors

We rely on a small number of third-party providers, each acting as a data processor under GDPR and similar regimes:

We will update this list before adding a new subprocessor, and the change will be reflected on this page.

International data transfers

Cloudflare, Google, Apple, Microsoft, Discord, Twitch, Axiom and GitHub are US-headquartered and may route or process data on US infrastructure. Neon stores the long-lived database in the EU or the US region you were assigned at sign-in. DeepSeek is headquartered in China and receives only counts and public target keys, never personal data. Where personal data originating in the EEA, UK, or Switzerland is transferred outside those regions, the transfer relies on the European Commission's Standard Contractual Clauses (and the UK Addendum / Swiss equivalents where applicable) in our agreements with those providers. The data we transfer is minimal: chiefly the salted-hash account identifier, your reaction records and reaction context, transiently the opaque provider id at the moment you sign in, the log lines and alert messages described under Subprocessors, (under the regional consent rules, only on the website) the standard Google Analytics first-party measurement payload, and (without identifying you, only on the website) the Cloudflare Web Analytics aggregated traffic beacon.

Security

All traffic between your browser and our servers is encrypted in transit with TLS 1.2 or higher. Long-lived account data is encrypted at rest by the managed database provider. Personal identifiers we keep are one-way hashes rather than raw values, and the one standing in for your provider id is keyed with a secret held outside the database. The state of a sign-in in progress and rate-limit markers live only in ephemeral edge storage that auto-expires within minutes. We do not run a password database, so there is no password store to leak. Source code for the extension is open and auditable on GitHub. If you find a weakness, the security policy covers where to send it, what is in scope, and the terms that keep testing authorized.

That said, no method of transmission over the internet or method of electronic storage is 100% secure. While we use commercially reasonable measures to protect the limited data we hold, we cannot guarantee absolute security. If we become aware of a security incident affecting your personal data, we will notify the relevant supervisory authority within 72 hours where required by law, and notify affected users directly when the incident is likely to result in a high risk to their rights and freedoms.

Requests received to date: 0. Checked on 2026-08-24. The number is updated when it changes, and it counts every request, including ones we refused.

We respond only to valid legal process from an authority with jurisdiction over the operator, who is established in British Columbia, Canada. An order issued elsewhere is not self-executing here — it reaches us through a Canadian court or the applicable mutual legal assistance route, and anything short of that is refused. We do not disclose data voluntarily. The one exception is a credible emergency involving a risk of death or serious physical harm, where the law permits disclosure without an order; a request of that kind is counted in the line above like any other.

What could be produced under compulsion: the keyed hash of a provider's opaque id and the provider's name, the hashed installation and session identifiers, the reactions currently active on an account with the context attached to them, entries in the public log (which anyone can already read), a report or survey submission if one exists, and the abuse decisions and linked-account reviews of the last 90 days if the account appears in one. We also hold the key that links a rotating pseudonym in that log back to an account, so an order could compel that link. It cannot be derived from the published log by anyone else, and we would rather state the limit than imply an impossibility we do not have.

What does not exist to produce: your name, your email address, or the raw provider id — the sign-in never requests the first 2, and the API waitlist and the uninstall survey are the only places an email address is stored, only because you typed it in; your raw IP address; any record of which counts you read, because a count lookup is answered without being stored and its log line omits the identifier; a list of pages you visited beyond the ones you reacted on or reported; the reaction history in your popup, which never leaves your browser; and any password, since there is no password store to compel.

We cannot notify you when a request names your account. Not as a matter of discretion — we hold a hash of a provider id and never a name or an address, so there is no way to reach you. That is a direct cost of the design, and the counter at the top of this section is what stands in for individual notice.

Marketing communications

We do not send marketing emails, newsletters, or promotional content. Signing in sends you nothing. The only messages you can ever receive from Emojery are, if you explicitly join the API waitlist, a single announcement when the public API launches, and, if you leave an address on the uninstall survey, one reply to what you wrote there. There is no other list to be on; waitlist removal on request is described in the next section.

API waitlist

The /api page has an optional form for joining the waitlist of the planned public API. If you submit it, we store the email address you enter plus a keyed hash of it (used only to de-duplicate repeat signups) in our database. This is the single place where a raw email address is persisted — everywhere else only the one-way hash exists.

The address is used for exactly one purpose: a single announcement when the public API launches. It is not added to any other list, not shared with anyone, and not used for any other messaging. After the launch announcement has been sent, the waitlist is deleted. To be removed earlier, open an issue via the privacy request template and include the address you signed up with.

The form is protected by Cloudflare Turnstile, a bot-check that runs in your browser when you submit; it does not track you across sites and we never see more than a pass/fail verdict for the submission.

Uninstall feedback

When you remove the browser extension, the browser opens a page on this website with an optional survey asking why. Opening the page stores nothing beyond the ordinary website analytics described above. Submitting the form is what sends data, and only what the form shows: the reason you picked, the free-text comments if you wrote any, and an email address only if you chose to enter one.

The submission is anonymous: the extension and its session are already gone by the time the page loads, so nothing links your answers to your account, and we do not attempt to re-identify you. If you leave an address it is stored raw (the second and last exception to the hash-only rule) for the single purpose of replying to you. It is not added to any list and not used for any other messaging. To have your answer removed, open an issue via the privacy request template.

Like the waitlist form, it is protected by Cloudflare Turnstile, and a salted hash of your IP address is used transiently to rate-limit the endpoint.

Uninstalling the extension does not delete your account or reverse your reactions. Deletion runs from the extension popup, because signing in there is the only way an account can be shown to be yours: we store the keyed hash of a provider id, never a name or an address, and a message sent from an email or filed as an issue proves nothing about who controls that provider account. Delete before you uninstall, or reinstall and sign in once with the same provider account to do it afterwards. For anything the popup cannot resolve, open a privacy request.

For users in the EEA, UK, and Switzerland, the legal bases under Article 6 GDPR are:

Automated decision-making

We do not make decisions about you using solely automated means that produce legal or similarly significant effects. Rate limits and anti-abuse checks are technical safeguards on the counters rather than profiling: an automated check can decline to count a reaction, or reverse reactions from a group of accounts that share one installation or vote in lockstep, and a language model may be asked for a second opinion on the aggregate evidence before that happens. None of this affects anything beyond whether a reaction is counted. You can ask for a human review of any such decision through Contact.

Your rights

You can permanently delete your account from the extension settings ("Delete account"). Deletion is immediate: your user row is removed, your reaction records and live anti-abuse counters are removed, and the aggregate counters for every reaction you previously submitted are decremented by one. We do not queue, review, or delay erasure requests. Four things are not removed by that step, each with the reason and the period stated in How long we keep it: a bug report you filed (removed on request), the installation ledger (90 days after last seen, not linked to an account), abuse decisions of the last 90 days, and a linked-account review that names the account. A request through Contact removes the report; the anti-abuse records are the one category we keep against the request, for the reason given in the next exception.

One structural fact to be clear about: the public, append-only transparency log that makes our counters verifiable identifies reactions only by rotating pseudonyms. It never contains your provider, your provider id, your account identifier, or anything others could link back to you, and entries from different periods cannot even be linked to each other without a secret key that only our backend holds and never publishes. Being straight about the other half of that: within a single period, the entries carrying one pseudonym are visibly the same pseudonym, and each entry records when it was added, rounded to the minute. That much is inherent to a log anyone can recount from scratch, and it is exactly why the pseudonym rotates and why the time is coarse. Deletion reverses every one of your entries by appending public revocation entries (that is exactly how the counters are decremented), but the pseudonymous entries and their revocations then remain part of the permanent public record: the log is published, cryptographically anchored, and independently mirrored precisely so that no one, including us, can rewrite it. In other words, deletion removes you; it does not, and by design cannot, rewrite history that no longer references you.

One narrow exception: if we have terminated your account for violating the Acceptable Use Policy, deleting it does not lift the termination. Your reaction records and device signals are still erased as above, but we retain the one-way keyed hash of your provider id (never the id itself) and the fact that the account was terminated, solely to enforce the termination and prevent ban evasion. This is the one case where a deleted account leaves a residual record.

Because we don't store the raw provider id, only its keyed hash, the database lists no accounts at any provider and cannot be turned into a list of them. A copy of it on its own cannot even be tested against a guessed provider account, because the key that produces the hash is held outside it. We hold that key, so we can compute the hash for a provider account you name and see whether an Emojery account exists — which is how an access or deletion request is matched when you are not signed in.

In addition to deletion, you have the rights of access, rectification, restriction, portability, and objection over the limited data we hold. Because we don't retain raw identifiers, an access request typically resolves to a confirmation that the hash of the address you give us is (or is not) on file, along with the reactions associated with it. If you believe we are processing your data unlawfully, you have the right to lodge a complaint with your local data protection supervisory authority. California residents have additional rights under the CCPA, including the right to know, the right to delete, and the right to opt out of sale or sharing. We do not sell or share personal information for cross-context behavioral advertising and never have.

Canada

The operator is established in British Columbia, so Canadian law applies to this processing directly and not only through the regimes named above: PIPEDA federally, and the province's Personal Information Protection Act. Under both you can ask what we hold about you, ask for it to be corrected, and withdraw consent — the same rights this page already grants everyone, exercised the same way. Complaints go to the Office of the Privacy Commissioner of Canada, or to the Office of the Information and Privacy Commissioner for British Columbia, and neither requires you to raise the matter with us first.

One consequence of storing the database in the EU or the US region assigned at sign-in (see International data transfers): while data sits in another country it is subject to that country's law, including access by its authorities under it. What such access could and could not reach is set out in Law-enforcement and government requests.

If we refuse a request

A denial is almost always one of two things: the address you authenticated with has no record on file, or the request asks us to rewrite the append-only log. Where we deny a rights request in whole or in part, we say which of the two it is and why. You can appeal that answer once, by replying on the same issue or email thread within 60 days, and we will answer with reasons. Be clear about what an appeal here buys: there is one person behind this project, so it is a second look rather than a second reviewer. Several US state privacy laws require an appeal route to exist; this is ours.

Escalating instead is always open to you and never needs our permission: your local supervisory authority in the EEA, the ICO in the UK, the FDPIC in Switzerland, the OPC or the BC OIPC in Canada, the California Attorney General, or the equivalent regulator where you live. You do not have to appeal to us first.

Acceptable use

The rules that apply to signed-in accounts and to API callers (one account per person, no automation, no circumvention of anti-abuse measures, no reactions on illegal targets) live on the acceptable use policy page.

Children

Emojery is not directed at children under 13, nor under the higher age of digital consent where one applies — 14, 15 or 16, depending on the EU member state. We do not knowingly collect data from anyone below the age that applies to them, and there is little to collect in the first place: reading counts needs no account. If a child signed in anyway, the account can be deleted from the popup's Account tab without contacting anyone, or you can tell us through the privacy request template and we will delete it.

Contact

Emojery is run as an independent project by a single individual established in British Columbia, Canada, who is the data controller for the processing described on this page. That is the whole organization: no company behind it, no group of entities, no third party deciding what happens to your data. The legal name and a postal address are provided on request, and to any supervisory or privacy authority that asks for them.

For privacy questions or formal requests under GDPR, the UK GDPR, the CCPA, or similar regimes, write to [email protected], open an issue on GitHub, or use the extension's Report tab and include the word "privacy" in the message. All three reach the same person; there is no separate legal department to escalate to. Non-privacy channels are listed on Contact.

Changes

We may revise this policy from time to time. The "Last updated" date at the top of this page reflects the most recent change. If a change materially affects what we collect, how we use it, or who processes it, we will surface a notice in the extension settings on next launch. Your continued use of the extension after that point counts as acceptance of the revised policy; if you disagree, you can delete your account from the popup's Account tab.