Privacy Policy
Niklas Rosenqvist ("we", "us") operates nitpik, an AI-powered code review CLI tool, and the nitpik.dev website. This policy explains what data we collect and how we handle it.
1. Data Controller
Niklas Rosenqvist
Mullbärsstigen 5, 196 34 Kungsängen, Sweden
admin@nitpik.dev
2. Data We Collect
2.1 General Inquiry Form
When you submit the contact form on nitpik.dev, we collect:
- Your name
- Your email address
- The message you sent
This data is sent to us via the EMAIL binding and stored in our email inbox (Proton Mail). It is not stored in any database. We use it solely to respond to your inquiry.
Lawful basis: Legitimate interest in responding to communications (Art. 6(1)(f) GDPR).
2.2 Dashboard Account
When you sign in to nitpik.dev/account to manage a subscription or create API keys, we store the following in a Cloudflare D1 database:
- Account — your email address, your Polar customer identifier (once you complete a checkout), and timestamps.
- Sessions — a SHA-256 hash of your session cookie value (the raw token is never persisted), your user agent, the time of issuance, and an expiry 30 days in the future. We also store a SHA-256 hash of your IP address combined with a server-side salt — this is a pseudonym used only for abuse triage and cannot be reversed by us to recover your real IP.
- Magic-link tokens — when you request a sign-in link, we store the SHA-256 hash of the one-time token along with the email address it was issued to, an expiry 15 minutes in the future, and the same kind of salted-and-hashed IP described above. Rows are marked as consumed once the link is clicked.
- API keys — when you create an API key for the CLI, we store its label, the SHA-256 hash of the key (the plaintext key is shown to you exactly once and never persisted), the first 12 characters of the key for display in the dashboard listing, and the timestamp of the last successful exchange.
We do not store passwords. Authentication is via single-use email magic links delivered by the Cloudflare Email Service.
Lawful basis: Performance of contract (Art. 6(1)(b) GDPR) for the dashboard service; legitimate interest (Art. 6(1)(f) GDPR) for security-related fields (hashed IP for abuse triage, session expiry).
2.3 Billing & Subscriptions via Polar
We use Polar.sh as our payment processor and Merchant of Record. When you subscribe to a commercial tier, Polar — not us — collects and stores the following on its own infrastructure:
- Your name and billing address
- Your VAT or tax identification number (if applicable)
- Your payment method details (processed by Stripe on Polar's behalf as a sub-processor)
- Invoice records, issued in Polar's own name and under Polar's own VAT number
Polar's processing is governed by Polar's Privacy Policy and their Data Processing Agreement. Stripe's processing of payment instruments is governed by Stripe's Privacy Policy.
From Polar we receive — and store in our Cloudflare D1 database for the lifetime of your subscription — only the following:
- Your email address
- Your Polar customer identifier
- The subscription identifier, status (
active,trialing,past_due,canceled,unpaid,incomplete, orrevoked), tier (Solo or Team), billing cadence (monthly or yearly), period start and end timestamps, and cancellation flag
In addition, for our own accounting we maintain a customer registry in Proton Drive and record the receipt of payouts from Polar in accounting software, as required by the Swedish Bookkeeping Act (Bokföringslagen, SFS 1999:1078).
Lawful basis: Performance of contract (Art. 6(1)(b) GDPR) for subscription management; legal obligation (Art. 6(1)(c) GDPR) for accounting records.
2.4 CLI Telemetry (Heartbeat)
The nitpik CLI sends a single anonymous heartbeat per review run to https://nitpik.dev/v1/heartbeat. This contains:
- A random run ID (UUID, generated per invocation, not linked to any user identity)
- Aggregate counts: number of files reviewed, diff lines, and reviewer profiles used
- Boolean flags: whether an active subscription entitlement is present, whether running in CI
- The target code-hosting forge for the run (e.g.
github,gitlab,forgejo), derived from the chosen output format and omitted for forge-agnostic runs — an aggregate adoption signal that carries no identity - CLI version string
This data cannot identify you. No source code, file names, review findings, IP addresses, user names, email addresses, or other personal information is collected or stored by the heartbeat endpoint. The heartbeat row is stored in the same Cloudflare D1 database solely for product improvement purposes.
Opt out of telemetry at any time via:
--no-telemetryflag on any commandNITPIK_TELEMETRY=falseenvironment variable[telemetry] enabled = falsein your configuration file
2.5 Code & LLM Provider Data
nitpik sends code diffs directly from your machine to your chosen LLM provider (e.g., Anthropic, OpenAI, Google, DeepSeek, xAI, Groq, Cohere, or Perplexity) using your own API key. This data never passes through nitpik's servers.
We do not see, store, proxy, or have access to your source code, diffs, review findings, or LLM provider API keys. Your relationship with your LLM provider is governed by that provider's own terms and privacy policy. You choose which provider processes your data.
2.6 Entitlement Tokens & Usage Records
To prove an active subscription to the licensed CLI surfaces, nitpik exchanges your nitpik license key for a short-lived signed entitlement token at https://nitpik.dev/v1/cli/entitlement. The signed token itself is cached on your machine at ~/.config/nitpik/entitlement.json (or the equivalent under %APPDATA% on Windows); we never see or store the cached token after it is issued.
When a token is issued we store, in our Cloudflare D1 database, a usage record linked to your account: your user identifier, your subscription identifier, the token type (online or offline), and the timestamp. The CLI refreshes roughly once per day, so this is a coarse, identity-linked record of when your subscription was active — never what was reviewed. We use it to understand product usage and to support the subscription. We also update the "last used" timestamp on the API key on file (Section 2.2).
Offline tokens (Team tier): for air-gapped environments, the dashboard can issue a longer-lived offline entitlement token whose expiry is aligned to your billing period. It is downloaded to your machine and set as an environment variable; we do not retain the token itself, only the usage record described above.
Lawful basis: Performance of contract (Art. 6(1)(b) GDPR) for entitlement; legitimate interest (Art. 6(1)(f) GDPR) for aggregate usage understanding.
2.7 GitHub App (Optional)
nitpik offers an optional GitHub App you can install on your repositories so reviews run automatically on pull requests or when you comment @nitpik review. The App is dispatch-only: it triggers a workflow in your own repository, which runs the review in your own CI, on your own model, posting via your own repository token. The App never receives, reads, proxies, or stores your source code, diffs, or review findings — the same guarantee as Section 2.5 applies.
When you install the App and link it to your nitpik account, we store in our Cloudflare D1 database:
- Installation record — the GitHub installation identifier, the account login and type (user or organization), your linked nitpik user identifier (set when you complete the post-install setup), and timestamps. You can unlink an installation at any time from your account page.
- Review-event records — for each review the App triggers, the installation identifier, your linked user identifier, the pull-request number, and the timestamp. These are used to associate App-triggered reviews with your subscription. As above, they contain no code, diff, or finding content.
To trigger workflows, we hold the App's private key and mint short-lived installation access tokens from GitHub on demand; these tokens are held in memory for the duration of the request only and are never persisted. When the App acts on your repository it calls the GitHub API; GitHub's processing of that interaction is governed by GitHub's Privacy Statement.
Lawful basis: Performance of contract (Art. 6(1)(b) GDPR).
3. Cookies
nitpik.dev uses two strictly necessary cookies on the dashboard. We do not use tracking pixels, analytics scripts, or advertising cookies.
| Cookie | Purpose | Properties |
|---|---|---|
nitpik_session | Identifies your signed-in session. The raw value is never stored server-side — only its SHA-256 hash. | HttpOnly, Secure, SameSite=Lax, 30 days |
nitpik_csrf | Cross-site request forgery protection. Mirrored in the X-CSRF-Token header on protected requests. | Secure, SameSite=Lax, JavaScript-readable, 30 days |
Both cookies are strictly necessary for the dashboard to function and are exempt from the consent requirement of Article 5(3) of the ePrivacy Directive. They are not used for tracking, profiling, or advertising. They are set only after you sign in and are cleared when you sign out.
The marketing pages of nitpik.dev (homepage, docs, legal) set no cookies of any kind.
4. Infrastructure & Sub-Processors
| Sub-processor | Role |
|---|---|
| Cloudflare | Hosts nitpik.dev as a Cloudflare Worker with static assets. Stores the D1 database described in Sections 2.2, 2.3, 2.4, 2.6, and 2.7. Routes inbound mail to our Proton Mail inbox via Email Routing. Delivers outbound transactional email (magic-link sign-in messages, ops notifications) via the Cloudflare Email Service. Processes IP addresses as part of standard CDN and DDoS protection operation. Governed by Cloudflare's Privacy Policy and their Data Processing Addendum. |
| GitHub | Only when you install the optional GitHub App (Section 2.7). We call the GitHub API to trigger workflows and read pull-request metadata on your behalf; the App never receives your code. We do not send GitHub any personal data beyond what is inherent to these API calls. Governed by GitHub's Privacy Statement. |
| Polar | Acts as Merchant of Record for subscription payments (see Section 2.3). Hosts the customer-facing checkout and self-serve billing portal. Collects and remits VAT and sales tax in its own name. Governed by Polar's Privacy Policy. |
| Stripe (sub-processor of Polar) | Processes payment instruments and operates the payout account through which we receive funds from Polar. We do not have a direct contractual relationship with Stripe; Polar's relationship governs. See Stripe's Privacy Policy. |
| Proton | Provides our email inbox (Proton Mail) and our document storage for the customer registry (Proton Drive). Governed by Proton's Privacy Policy. |
5. Data Retention
| Data | Retention |
|---|---|
| General inquiry emails | Up to 12 months after the inquiry, then deleted from the inbox. |
| Telemetry heartbeats | 12 months, automatically purged by a monthly cron job. |
| Magic-link tokens | 15 minutes (single-use); the consumed row is retained for up to 30 days for audit purposes. |
| Dashboard sessions | 30 days (rolling); expired rows are kept until manually purged. |
| Dashboard account record | For as long as your account exists; deleted on request (Section 6). |
| API keys | For as long as you keep them active. Revoked keys are soft-deleted and retained for audit. |
| Subscription records (in D1) | For the lifetime of the subscription plus the legal retention period below. |
| Entitlement usage records (Section 2.6) | For the lifetime of the subscription; used for usage understanding and support. |
| GitHub App installation records (Section 2.7) | For as long as the App is installed and linked; removed when you unlink or uninstall. |
| GitHub App review-event records (Section 2.7) | For the lifetime of the linked subscription; contain no code or finding content. |
| Webhook idempotency log | Indefinite; rows are small and used only to prevent duplicate processing. |
| Billing records and customer registry (Proton Drive, accounting software, payout receipts) | 7 years after the end of the fiscal year in which the transaction occurred, as required by the Swedish Bookkeeping Act (Bokföringslagen, SFS 1999:1078). |
Where personal data is retained to comply with a legal obligation, it will not be used for other purposes during the extended retention period and will be deleted once the obligation expires.
For billing data held by Polar, retention is governed by Polar's own policies — please consult Polar's Privacy Policy for the authoritative statement.
6. Your Rights Under GDPR
If you have a dashboard account, have submitted personal data through a contact form, or have completed a subscription checkout via Polar, you have the right to:
- Access the personal data we hold about you
- Rectify inaccurate data
- Request erasure of your data (subject to the legal retention obligations in Section 5)
- Restrict processing
- Data portability
- Object to processing
- Lodge a complaint with the Swedish Authority for Privacy Protection (IMY)
To exercise any of these rights against data held by us, contact admin@nitpik.dev. To exercise rights against data held by Polar, please use the contact information in Polar's Privacy Policy; Polar acts as an independent data controller for the billing data described in Section 2.3.
7. Changes
We may update this policy from time to time. The effective date at the top of this page will be updated accordingly.
8. Contact
For privacy questions: admin@nitpik.dev
For general inquiries: contact@nitpik.dev
Automated emails (magic-link sign-in, ops notifications) are sent from noreply@nitpik.dev and are not monitored — please reply to one of the addresses above instead.