Privacy
Crosstabs is designed around local file parsing and explicit AI actions. This page describes the current app behavior, not a legal compliance certification.
Spreadsheet files
- CSV, TSV, TXT, and XLSX files are parsed in the browser.
- Crosstab tables, filters, weights, percentages, and statistics are computed from the parsed browser data.
- The original spreadsheet file is not uploaded for normal crosstab calculation.
- If you explicitly save a project, the parsed dataset and current settings are stored in this browser's IndexedDB when available, with localStorage used only as a compatibility fallback. Analysis templates use localStorage.
- A full .ctproj export is an explicit download containing respondent rows and the complete project graph. It is checksummed but not encrypted. A manifest-only export removes rows and specified data-derived fields but can retain authored labels, findings, comments, audit details, and branding.
Aggregate result links
- Creating a share link is an explicit action. The link places aggregate counts, row and column labels, and user-selected context in the URL fragment (the part after #).
- The source spreadsheet file and respondent-level rows stay in the creator's browser and are not included in the share link.
- The recipient's browser decodes the fragment. Browsers do not include URL fragments in HTTP requests or HTTP referrer headers, so Crosstabs does not receive or store the fragment through this feature.
- Anyone who obtains the complete link can read its aggregate values and context. Fragment encoding is not encryption or access control.
- These links have no expiration or revocation mechanism. Removing local browser data does not invalidate copies of a link that were already shared.
AI features
- AI summaries are opt-in. Crosstabs does not send analysis context until you click Analyze or ask a question in the AI panel.
- AI analysis is opt-in. Before sending, the workspace discloses the structured aggregate context: labels, counts, percentages, residuals, statistics, warnings, active filters, weight context, and cell references.
- The /api/chat request excludes the original spreadsheet, filename, and respondent rows. A typed follow-up question is sent verbatim with the disclosed aggregate context.
- The AI request does not include the original spreadsheet file.
- Open-end coding is a separate, explicit action. After you accept its disclosure, only the selected column's non-empty response texts, stable row keys, coding mode, and any supplied theme definitions are sent through Vercel AI Gateway; other columns, filenames, and the original file are excluded.
- The Gateway and selected model provider process those response texts under the configured provider controls and their applicable terms. Crosstabs does not persist the coding request in its application database or write prompts, response text, provider response bodies, or nested provider errors to application logs.
- Returned open-end evidence is accepted only when it is a verbatim substring of the attributed response; otherwise Crosstabs substitutes bounded text from that response. Themes and assignment evidence are saved only when you keep them in the browser-local project, where they remain reviewable and undoable.
Remote MCP request logs
- The public remote MCP accepts methodology identifiers, search text, optional display labels, and aggregate contingency matrices. It has no respondent-file or raw-row upload tool.
- Every remote MCP response receives a server-generated correlation identifier and an aggregate request-duration metric for production diagnosis.
- Structured runtime events contain only the HTTP method, a fixed allowlisted MCP method name, anonymous-or-bearer mode, allowed/rejected/absent browser-origin state, response status, and duration.
- Authorization values, tool arguments, search text, labels, matrices, project data, response content, and respondent values are not written to the application log event.
Anonymous usage analytics
- On production deployments, Crosstabs uses Vercel Web Analytics for pageviews and coarse product events. The analytics client is cookie-free; small sessionStorage records remember only the acquisition surface, upload/sample/manual input, funnel stage, and a versioned coarse acquisition-provider and landing-cluster category for this browser tab.
- Before analytics URLs are redacted, recognized UTM or referring origins are reduced to an allowlisted provider category such as OpenAI, Claude, Gemini, Perplexity, conventional search, other referral, or direct/unknown. The initial page is reduced to a coarse cluster such as calculator, method guide, Chinese content, or trust. Raw URLs, UTM values, referrer paths, query strings, and fragments are not stored. Aggregate snapshot routes under /s are excluded, and custom events are also suppressed on /s after client-side navigation.
- A fresh activation can also create one random anonymous attempt id in Crosstabs' Neon database. Its record contains only schema version, coarse surface/input/acquisition/landing enums, a browser-candidate-or-automation class, release id, start time, and timestamps for dataset-ready, sample/upload, first-table, AI-answer, and export milestones. On every new receipt write, the application purges records older than 180 days. It contains no account id, IP address, raw user agent, spreadsheet contents, rows or cells, filename, project id or name, variable or category label, filter value, AI question, raw URL, or share fragment.
- The activation receipt endpoint accepts only same-origin, size-bounded, exact-schema requests. Its per-instance abuse backstop uses a short-lived HMAC pseudonym derived from the request address; neither the address nor that pseudonym is written to the activation database. Vercel supplies platform DDoS mitigation; a path-scoped Firewall observation rule is staged so a durable rate limit can be tuned from real traffic before enforcement.
- Canonical Vercel activation milestones contain two allowlisted enum properties. The separate anonymous receipt joins milestones by attempt so conversion is measured in attempts, never inferred from unrelated event totals or described as unique people.
- Other product-usage events use coarse buckets such as file type, file-size range, row-count range, variable-count range, result shape, and selected feature. They do not contain the original spreadsheet file or respondent-level values.
- Vercel may process the redacted path, time, referring origin, approximate geography, browser, operating system, and device category to produce anonymous aggregate reports. Crosstabs sets a strict-origin referrer policy so same-site paths and queries are not forwarded as referrer data; UTM query parameters are discarded after any recognized source is reduced to the coarse provider category. Vercel analytics retention follows Vercel's current policy; Crosstabs applies the receipt-write cleanup boundary described above to its anonymous activation records.
See Vercel's Web Analytics privacy documentation for current vendor details.
Browser storage
Saved projects, analysis templates, and report settings stay in this browser profile. Projects are versioned and stored in IndexedDB when available; older localStorage projects are migrated locally. They can be removed from the home page or workspace. Clearing site data in the browser also removes them. Session-scoped acquisition state is removed when that tab session ends or site data is cleared. Crosstabs does not silently delete an older project to enforce a fixed project count; a failed browser-quota write is reported instead. Export important projects before clearing data or changing profiles.