Privacy
Private where it matters. Explicit where it leaves.
- Account required
- Never
- Claims stored
- On your device
- Analytics
- None
- Non-self hosts in the CSP
- None
01/Where it runs
On your device.
@claimback/core is pure, isomorphic TypeScript: everything ambient it needs — today’s date, airport distances, carrier nationality — is handed to it as an argument. That means the same code that runs in the API route runs in a browser tab, and the browser tab is where your claim is actually evaluated.
Letter assembly is the same. Templates emit a structured block tree and the formatters turn it into text, markdown or print-ready HTML in the page. A PDF goes through your browser’s own print-to-PDF rather than a bundled layout engine, which is why your name and address never have to reach a server to get a document out of this.
- Working out what you are owed
- Every registered regime, evaluated in the tab. No request is made.
- stays here
- Assembling the letter
- Rendered from the same evaluation, in the same tab, with your name and address never serialised anywhere but locally.
- stays here
- Tracking a claim you have sent
- Kept in this browser's local storage. There is no account to key a server copy to, and no server copy.
- stays here
- Calling the public API instead
- Optional, and for other people's software. A request is evaluated and discarded within the request; nothing is written down.
- not retained
02/The proof
The policy, in full.
A privacy policy is a promise about behaviour you cannot observe. A Content-Security-Policy is a rule the browser enforces regardless of intent. It blocks unlisted third-party destinations and makes every permitted authentication host visible below.
The directive that carries the whole promise is connect-src 'self'. Every fetch, every XMLHttpRequest, every WebSocket and every beacon is confined to this origin plus the explicitly named authentication host. There are no analytics, advertising or session replay destinations hidden behind wildcards.
- default-src
- 'self'
- this origin only
- script-src
- 'self' 'unsafe-inline'
- this origin only
- worker-src
- 'self' blob:
- this origin only
- style-src
- 'self' 'unsafe-inline'
- this origin only
- img-src
- 'self' data: blob:
- this origin only
- font-src
- 'self' data:
- this origin only
- connect-src
- 'self'
- this origin only
- frame-src
- 'none'
- this origin only
- form-action
- 'self'
- this origin only
- frame-ancestors
- 'none'
- this origin only
- base-uri
- 'self'
- this origin only
- object-src
- 'none'
- this origin only
default-src 'self';
script-src 'self' 'unsafe-inline';
worker-src 'self' blob:;
style-src 'self' 'unsafe-inline';
img-src 'self' data: blob:;
font-src 'self' data:;
connect-src 'self';
frame-src 'none';
form-action 'self';
frame-ancestors 'none';
base-uri 'self';
object-src 'none'Wrapped at the semicolons for reading. This is the policy this particular server is sending: in development it additionally permits 'unsafe-eval', because Next's hot-reload runtime evaluates the modules it swaps. A production response does not carry it.
And the rest of the response headers
- X-Content-Type-Options
- nosniff
- Referrer-Policy
- strict-origin-when-cross-origin
- X-Frame-Options
- DENY
- Permissions-Policy
- camera=(), microphone=(), geolocation=(), interest-cohort=()
03/Storage
One copy, and you hold it.
Nothing here asks who you are. Not the coverage catalogue, not the letters, not the calculator, not the API, and not the claim flow — the part that would ordinarily be behind a signup is the part that most needs to stay on your machine.
Claims you track are written to this browser’s local storage as one versioned document. That document is also the export format, so taking your work to another device means downloading a file and importing it there. It is a deliberately manual step: an automatic one would require an account, an account would require a server copy, and a server copy is the thing this page exists to say does not exist.
The consequence runs both ways, and it is worth stating plainly rather than burying. Clearing this browser’s site data deletes your claims, and nobody — including us — can restore them.
- Where the claims file lives
- Local storage, in this browser, under one key. Readable by you at any time from Data & export.
- this device
- What the server stores about you
- There is no user record, because there is no user. Nothing is keyed to a person anywhere in this system.
- nothing
- Moving between devices
- Export a JSON file and import it. The same document the app reads, with a version marker so a stale export still opens.
- a file you carry
- If you clear your browser data
- There is no backup to restore from, because a restorable backup would mean a copy existed somewhere we could read.
- the claims are gone
04/Commitments
What is not collected.
No third-party analytics, and no trackers.
Not an analytics script, not a heatmap, not a session recorder, not a pixel. The CSP names this origin and nothing else, so there is no advertising or analytics destination for anything to be sent to.No identity documents, ever.
No passport scan, no proof of address, no selfie. A tool that tells you about a €600 claim has no business holding the documents used to open a bank account.No accounts, so no account data.
There is nothing to sign up for. No email address, no password, no profile — and therefore no user table to breach, subpoena or sell. The public API processes a request and discards it.No echo of what you sent.
The evaluation response deliberately omits the claim you submitted. You already have it, and not reflecting personal data back means a misconfigured cache or a logged response body cannot leak it.No exception message in an error.
A failure returns a short correlation reference. A rules-engine throw can contain a booking reference or a home address, and that must not travel back over the wire even to the person who sent it.
If you think any of this is wrong, it is checkable: the source is AGPL and published at github.com/Soham109/duesday, the policy above is the header your browser received, and the API is open without a key so you can watch exactly what it returns.