# Privacy notice — pilot v0.2.0

Privacy questions and pilot feedback: `payoutreconciler@proton.me`. Do not email financial files, transaction exports, credentials, or unredacted account data.

Your financial files and transaction data stay in your browser. The app sends one anonymous aggregate pageview event per page load to the same-origin `/api/pageview` endpoint to measure overall traffic; it contains no cookies, identifiers, or financial data. Links may include short campaign labels (`utm_source`, `utm_medium`, `utm_campaign`, `utm_content`) so we can compare public channels; only those validated labels are recorded, never the URL or referrer. If you opt in, anonymous technical product events are sent to the same-origin `/api/telemetry` endpoint and retained in Cloudflare Workers Logs to improve file compatibility and understand pilot usage. Financial contents are never included.

Telemetry is off by default. Consent is not stored and resets when the page is refreshed or closed. The application uses no cookies, browser storage, fingerprint, account identifier, or telemetry session identifier.

## Aggregate pageview schema

The pageview endpoint receives no request body. The Worker logs `event: "page_view"`, a UTC timestamp, coarse Cloudflare location buckets (`country` and `colo`) when available, and only valid lowercase campaign labels (maximum 32 characters). It does not include a URL, referrer, IP address, user agent, cookie, identifier, or financial data.

## Exact telemetry schema

Every accepted event contains exactly these string fields:

| Field | Allowed value |
|---|---|
| `app_version` | Application semantic version. |
| `event` | `landing_view`, `import_started`, `import_completed`, `import_failed`, `comparison_completed`, `support_contact_clicked`, or `runtime_error`. |
| `format` | `csv`, `camt053`, `mt940`, `ofx`, `qfx`, `qbo`, `qif`, `bai2`, `xlsx`, `pdf`, or `unknown`. |
| `stage` | `landing`, `file_read`, `format_detection`, `role_detection`, `parsing`, `normalization`, `reconciliation`, `support`, or `runtime`. |
| `error_code` | Allowlisted uppercase technical code; `NONE` for a successful import. |
| `page_count_bucket` | `0`, `1`, `2-10`, `11-50`, `51-100`, `101+`, or `unknown`. |
| `rows_accepted_bucket` | `0`, `1-5`, `6-20`, `21-100`, `101-500`, `501-1000`, `1001+`, or `unknown`. |
| `rows_rejected_bucket` | Same row buckets. |
| `browser_family` | `Chrome`, `Edge`, `Firefox`, `Safari`, or `Other`. |
| `timestamp` | UTC ISO 8601 timestamp. |

The endpoint rejects extra or missing fields, invalid values, cross-origin requests, non-JSON bodies, and bodies over 2 KiB.

## Never collected by telemetry

CSV/PDF/XLSX contents or bytes; amounts; transaction dates; IBAN, account, or card numbers; payout or transaction IDs; references; descriptions; filenames; extracted PDF text; raw rows; column names; free-form messages; stack traces; cookies; persistent identifiers.

## Provider, retention, and network metadata

Hosting and telemetry provider: Cloudflare Workers Static Assets / Worker / Workers Logs. Pilot event retention on Cloudflare's Free plan is up to **3 days**. Cloudflare invocation logs are disabled for this deployment, so automatic request metadata such as the connection IP is not retained in Workers Logs. The application code does not read or log the connection IP address. Cloudflare necessarily sees IP and request metadata transiently at the network/infrastructure layer when serving the page and endpoint. No third-party telemetry SDK is used.

The optional diagnostic download is separate: it is generated locally only after a user click and is never uploaded automatically.
