What happens to your data, with the receipts.
Five claims about how Outsample handles customer data, each stated only as far as the code and tests in the repository support it. The file paths and test names sit next to each claim so you can check them, not take them on faith.
One tenant cannot read or write another tenant's rows.
Every table that holds customer data carries row-level security, enforced by the database itself. The API talks to Postgres as an unprivileged role that cannot bypass those policies. A standing isolation gate runs as that same role, not as an administrator, and proves the boundary from the outside: cross-tenant reads return zero rows, cross-tenant writes touch zero rows, and requesting another tenant's resource returns 404, never a revealing 403.
The gate is a 142-cell matrix covering database reads and writes, API-level access with real sessions, uploads, derived artifacts, billing rows, and account deletion. It is a committed, re-runnable regression asset, and it re-runs whenever the schema or a tenant-touching code path changes. The latest committed run: 142 of 142 cells pass, verdict G-ISO GREEN.
Uploads are private objects with server-derived keys.
Uploaded PDFs are stored as private objects in an R2 bucket; no
object is ever written with a public ACL. Keys are derived on the
server as tenant/<id>/<sha256>.pdf, never
from request input, so a tenant's requests can only construct keys
under its own prefix.
Serving is license-gated. The PDF endpoint returns your own uploads on a strict tenant match. A corpus paper you did not upload is served only when its redistribution tier is Open; restricted, unknown, or unset tiers return 404. Fail-closed, and 404 rather than 403, so the response never confirms what exists.
Deletion is a staged purge, and we say what stays.
Today the deletion path is operated by us: an admin-triggered endpoint, run on request. A self-serve flow in Settings calls the same functions and ships before public launch.
Requesting deletion starts a 7-day window. API keys are revoked, sessions are revoked, the Stripe subscription is cancelled, and sign-in is blocked for the whole window; within it, the deletion can still be cancelled. After the window, a staged purge deletes stored objects before database rows, sweeps the storage prefix for orphaned objects the database cannot name, deletes the SuperTokens user record, and ends by deleting the tenant row itself. Each stage is idempotent and records its own evidence, so an interrupted purge resumes rather than restarts.
What stays: the Stripe customer and its invoice records, which we are legally required to retain for tax and accounting. Nothing else survives the purge.
Every AI request carries a no-retention directive.
We direct no-retention on every AI request: all requests carry
OpenRouter's data_collection: deny directive, which
restricts routing to provider endpoints that do not store or train
on prompts. Your queries and documents are processed by Anthropic
models under their API data policy, which does not use API content
for training.
The scope of that claim, precisely: the directive is a routing restriction enforced by OpenRouter against its classification of provider data policies, not a per-request guarantee of what a provider retains. Anthropic's standard API policy holds content for a bounded abuse-monitoring window, which is why this page says no-retention directive and not zero retention.
The directive defaults on, and it cannot be bypassed by a new code path: a test fails if any code calls the model SDK outside the one wrapped client, and another fails if the default ever flips off.
Errors are scrubbed, and analytics never carry your queries.
Error reports go to Sentry through a scrubbing hook that runs before anything leaves the app. Request bodies, query strings, cookies, and environment data are dropped; emails, API keys, and token-shaped values are redacted by pattern; and a test asserts that a sample research query never survives serialization into an event.
Product analytics run server-side to an EU-hosted PostHog instance. The page loads no third-party analytics script: events post to our own origin, and the server keeps a whitelist of allowed property keys and drops everything else. The event schema has no field for query text, so your questions are structurally not part of any analytics event.
How the product itself behaves, including where it fails, is on the methodology page with three real runs and their raw output.