Privacy policy

Last updated: September 2026

Pulli is a native macOS download manager. We do not use usernames or passwords. Your account is a random key like pulli-XXXX-XXXX-XXXX. This policy covers three different piles of data, because they are not the same.

Data controller

Pulli is the data controller for the account record described here. For privacy inquiries, contact privacy@pulli.app.

Three kinds of data

Account record. The key, optional email, one activation per Mac, and the coarse country at mint. GDPR treats this as personal data even if we never learn your name. The key singles the account out.

Product events and opt-in metrics. No license key on the row. Events carry a monthly hash of the device id. After that month's key dies, we cannot join the row back to a device. Metrics rows store no device id.

What you fetch. URLs, files, cookies, and the queue stay on your Mac. The extension forwards capture to the local app only.

No name required

You can generate a key and never attach an email. We still hold the key, the country it was minted in, and one row for the Mac you activate. That is an account without a name. Attaching an email is only for recovery and receipts. You can detach it later.

Paying for Pro is the one place a card name appears. Creem handles that as merchant of record and does not pass the card back to us.

What we process and why

For a field-by-field breakdown of every data point we store, see our transparency page . The table below covers the legal basis for each processing activity.

Contract
License activation, the one device seat, and feature gating. We need this record to run your key on the Mac you activate.
Legitimate interest
Coarse country on the key (install map), idle-seat cleanup, rate limits, and website operator error logs. OS version sits on the activation row because it is part of running the license, not a separate analytics product. You can object.
Consent
Optional email, and the two Settings toggles for usage and diagnostic sharing. Both toggles are off by default. Withdraw by detaching the email, turning the toggles off, or deleting the key.

How long we keep it

License and activationsUntil you delete the key
The license and its activation row stay until you erase the account. An activation that has not checked in for 180 days is released so you can use the one seat on another Mac. Free keys do not expire.
Event rows24 months
Page views, app downloads, and update checks. No license key on the row. The device id is replaced at write time with a hash under a per-month key held only in edge storage. That key lives for the current month plus one, then dies. After it is gone, we cannot map those rows back to a device. Distinct-device counts are exact only while the month key is live. A nightly job deletes rows older than 24 months.
IP addressUp to 1 hour
Never written to the database. Cloudflare's edge store holds a keyed hash as a rate-limit counter, which expires on its own. We read the IP once at key mint to store a coarse country. Nothing else.
EmailUntil you detach it or delete the key
Only if you attached one.
Payment processor recordsPer Creem's policy
Creem keeps transaction records for tax and accounting. See creem.io/privacy.
Cloudflare request logsUp to 72 hours
Platform logs expire on their own. We cannot search or delete a single visitor's entries while they are alive.
Website operator error logs (Axiom)30 days
Failed API terminals and Worker error lines, when Axiom is configured. Successful requests stay out. No license, device, or diagnostics id. Not controlled by Settings.
App and extension diagnostic logs (Axiom)30 days
Only if a share toggle is on. Tagged with a random diagnostics id, not your key. Turning both toggles off stops new lines and deletes the local id. Existing lines expire at the end of the window. We cannot single yours out before then.
Usage metrics24 months
If either share toggle is on, daily resource summaries and feature-preference snapshots land in our database with no license or device id. The request is signed so only an activated install can post. Nothing from that auth is stored. Turning both toggles off stops new uploads. A nightly job deletes rows older than 24 months.

Who else sees your data

CreemMerchant of Record
Processes payments, stores card details, and manages subscriptions. We never see the card. Checkout sends Creem an opaque internal account id and, if you attached one, your email. The license key and IP are not sent. Currency and tax come from the billing details you enter at checkout. Creem is the controller for payment data. Their notice is at creem.io/privacy.
CloudflareInfrastructure
Hosts the website and API on Cloudflare Workers. Derives a coarse country from IP at mint time, and holds a keyed hash of the IP briefly in edge storage for rate limits. Cloudflare is a processor under our instructions. Their DPA is at cloudflare.com/gdpr.
ResendEmail delivery
Sends the only emails we send: the key when you attach an email, and the key again when you recover it. Resend receives the address and the message, which contains the license key. No newsletters. Resend is a processor under our instructions. Their policy is at resend.com/legal/privacy-policy.
AxiomLogs (operator + opt-in app)
Two rails. Website operator errors: failed API terminals and Worker error lines, when Axiom is configured. No license, device, or email. App and extension diagnostics: only if you turn on a share toggle in Settings. Those lines use a random diagnostics id, not your key. We strip URLs, paths, emails, tokens, and credentials before anything leaves your Mac. Axiom is a processor. Their policy is at axiom.co/privacy.

International data transfers

Pulli runs on Cloudflare's edge. A request may be handled in a data center outside your country. Cloudflare, Creem, and Resend use Standard Contractual Clauses for transfers from the EEA. Resend also relies on the EU-US Data Privacy Framework. Opt-in diagnostic lines go to Axiom's EU region by default.

Cookies and tracking

No analytics scripts, no advertising pixels, no third-party cookies, and nothing that follows you between sites. The website sets exactly two first-party cookies, neither of which identifies you:

  • viewport remembers whether your screen is phone, tablet, or desktop sized so the first paint is the right layout. Holds one word. Expires after a year.
  • pulli_unlock is only set while the site is in early access, and only after you enter an access code. It records that the code was correct and nothing else.

The desktop app stores your license key locally on your machine; that is device storage, not a cookie.

We do not respond to Do Not Track signals. The site has no advertising pixels or third-party analytics. We still record page views, downloads, and update checks as event rows with no license key, as described above. California residents: we do not sell or share your personal data for cross-context behavioral advertising, and no such sale has occurred in the past 12 months.

Browser extension

The Pulli Chrome extension intercepts downloads in the browser and forwards them to the Pulli desktop app on your Mac. It does not download anything itself. Capture traffic uses Chrome's native messaging API to a locally registered host (app.pulli.host) installed by the Pulli app. The extension never holds an Axiom token and never opens a direct connection to Axiom or pulli.app for telemetry.

When a download is intercepted, the extension reads the following from the browser and forwards it to the local app only:

  • Download URL. The address of the file being fetched.
  • Referrer URL. The page that initiated the download.
  • Cookies. Session cookies for the download's domain, so authenticated downloads succeed in Pulli without re-authenticating.
  • Filename and file size. The suggested name and expected size from Chrome.

Capture data stays on your machine. It is not sent to pulli.app or any other remote endpoint.

If you turn on a share toggle in the Pulli app, the extension may also send sealed diagnostic events (level, short message, machine error kind, outcome) to the local app over the same native channel. The app applies the same Settings gate and redaction as its own logs before anything can leave for Axiom. With both toggles off, those diagnostic events are dropped. The extension does not run analytics SDKs, ad pixels, or remote trackers.

To catch drag-to-fetch gestures, the extension asks Chrome for access to every site you visit and runs a small content script in every page and frame as it loads. That access is broad by necessity: a download can start anywhere. The script reads link URLs and page titles when you drag a link, and sends them to the background script for forwarding to the local app. It does not read page content, browsing history, keystrokes, or mouse movement outside of drag gestures, and nothing it reads for capture leaves your machine.

Security

Traffic between the app, the website, and the API uses HTTPS. License keys are signed with Ed25519 and verified on every request. The key is minted on our server, stored there as a sealed account record, and kept on your Mac in the keychain. The operator console can read license and activation rows when we run the product. We do not read what you fetch. Those files never leave your Mac.

If a data breach occurs that risks your rights, we notify the relevant supervisory authority within 72 hours and inform you directly if the breach is likely to result in a high risk to you.

Your rights

Under GDPR and UK GDPR, you have the following rights. Email privacy@pulli.app with your account key. If you only have the recovery email, send that and we look the key up.

Access
Ask for the record tied to your key. We send the license, its activations, and the email if one is attached. That is the same record you can already open at /key. Event and metrics rows have no key on them, so we cannot attach those to a reply.
Erasure
Delete the key at /key, or email us. We delete the license and its activations. Event and metrics rows stay because we cannot find yours. They expire after 24 months. Axiom lines expire after 30 days. Cloudflare request logs expire within 72 hours. Creem keeps payment records under creem.io/privacy. Deleting the key does not cancel a Creem subscription. Cancel that in Creem's customer portal first.
Portability
Ask us and we send that same /key record as JSON. There is no separate export file today.
Objection
Tell us to stop a specific processing purpose. We honor it unless we have a legal ground to continue.
Rectification
Attach or update your email at /key, or tell us what is wrong.
Restriction
Ask us to store the account and stop using it while a dispute is open. We freeze that record until we resolve the request.
Complaint
Lodge a complaint with your local data protection authority. Find your DPA at edpb.europa.eu. You do not need to contact us first.

Children

Pulli does not target children and we do not knowingly process data from anyone under 16. If you believe we hold data from a minor, contact us and we will delete it.

Changes to this policy

We update this page when our data practices change. The "last updated" date above reflects the most recent revision. Material changes will also be announced in the app.