Don't trust us. Verify.
You're about to paste a secret into a website you found on the internet. You should be suspicious. Here's exactly what our server can and cannot see, and how to check it yourself instead of taking our word for it.
The 30-second proof (do this right now)
Open your browser's developer tools. Go to the Network tab. Create a note with the text "test secret". Watch every request that leaves your browser.
You will see a POST to /api/v1/note/. Click it. Look at the request body.
You'll find a field called encrypted — a blob of random-looking bytes.
You will not find the words "test secret", your password, or the key anywhere in that request.
The QR code on the share screen is drawn in your browser, so the link doesn't leave the page that way either.
// What your browser sends to our server when you create a note:
{
"encrypted": "a4f8c2e1...b7d903fa",
"iv": "3c9a1f...",
"kdf": "sha256",
"viewLimit": 1,
"expiresIn": 86400
}
// The link you share keeps the key in the URL fragment:
https://voidnote.net/n/abc123#e5f6a7b8...
// ↑ Browsers do not send the part after # to the server.
Opening the note works the same way. The reader's browser asks our server for the ciphertext by its token id, then decrypts it with the key from the fragment. Our server only ever returns ciphertext.
Older links in the form /note/…, which the website used to create and
older versions of the mobile apps still do, carry the key in the path instead. When one of those is opened, the reader's browser sends the full link,
our server decrypts the note in memory, returns the text over HTTPS and burns the view. The key is not saved, but for that
moment our server has both the key and the plaintext. These links expire within 30 days of being created.
For /n/ links this isn't a setting we can toggle. It's how the HTTP protocol works. URL fragments are
not sent by the browser in any network request.
RFC 3986 §3.5
— this has been the standard since 2005.
The cryptography — three lines
secret = 16 random bytes ← generated on your device
key = SHA-256(secret) ← derived in your browser
ciphertext = AES-256-GCM(your_secret, key, random_iv)
With a password, the key is PBKDF2-SHA256(password, salt = secret, 600,000 rounds)
On create, server receives: ciphertext + iv
On create, server never receives: secret, password, key, or plaintext
On read: /n/ links send only the token id
AES-256-GCM is a widely used, publicly analysed encryption standard. Without the key, the ciphertext is computationally indistinguishable from random noise. There is no backdoor. There is no master key. We didn't invent this — we're using a standard that has been publicly analysed by thousands of cryptographers for over two decades.
If AES-256 had a weakness, the problem would be vastly larger than VoidNote. Every bank, every government, every VPN, and every encrypted messaging app on earth would be compromised.
Read the source code
Every SDK is open source. The encryption logic is short and readable — no obfuscation, no magic.
| Language | Crypto file | Lines |
|---|---|---|
| TypeScript | src/crypto.ts | ~60 |
| Python | voidnote/crypto.py | ~50 |
| Go | crypto.go | ~45 |
| Rust | src/crypto.rs | ~55 |
| Zig | src/crypto.zig | ~40 |
| Java | CryptoEngine.java | ~65 |
If you can read code at all, you can verify the encryption flow in under five minutes.
Encryption happens entirely in the client before any network request is made. The one
server-side step is decrypting older /note/… links when they are opened, described above.
What we store vs. what we don't
| Data | Stored? | Why |
|---|---|---|
| Your plaintext secret | Never | Encrypted before upload; older /note/ links are decrypted in memory when opened, not saved |
| Encryption key | Not with the note | Derived client-side, lives in the link (fragment for /n/ links, path for older /note/ links). Saved to your account only if "Send to my devices" in an older mobile app put the link in your inbox |
| Ciphertext + IV | Yes | Useless without the key, which isn't stored with it |
| Token ID (lookup key) | Yes | So we can retrieve the right ciphertext |
| View count / expiry | Yes | To enforce self-destruction rules |
| Who created a note | Only if signed in | Notes made with an account are linked to it so they show in your history. Notes made without one carry no owner |
| Your IP address | Not with notes | Used as the key of short-lived rate-limit counters (for IPv6, only the /64 prefix), deleted within about a day |
| Analytics / tracking scripts | None | No Google Analytics, no pixels, no tracking |
If our entire database were leaked tomorrow, the attacker would have a collection of random-looking byte blobs and token IDs, with no keys stored alongside them. The exception is links you saved to your inbox with "Send to my devices": those include the key.
What happens if we get hacked
Let's say the worst happens. Someone gets full access to our Cloudflare D1 database, our KV store, and our R2 bucket. Here's what they find:
-- notes table
token_id: "a1b2c3d4e5f6..."
ciphertext: "7f3a9c...82d1e0" ← random bytes, no key
iv: "3c9a1f2b..."
views_remaining: 1
expires_at: 2026-03-03T10:00:00Z
-- That's it. No plaintext. No key. No user content.
-- The notes table alone decrypts nothing.
Contrast this with most "secure" messaging services: if their database leaks, every message is readable because the server held the keys. With VoidNote, stolen notes are ciphertext without their keys.
A demand for stored notes produces the same result: ciphertext and metadata, because notes are stored without keys
(links you saved with "Send to my devices" are the exception).
The other exception is the moment an older /note/… link is opened, when
our server briefly handles the key and plaintext. /n/…#key links, the kind created today, avoid that.
We are a registered company, not an anonymous website
VoidNote is built and operated by Quantum Encoding Ltd, a company registered in England and Wales (Company No. 16575953), with a registered office at 33 Oxford Street, Coalville, LE67 3GS, United Kingdom.
We're a real company with real filings, subject to UK law including UK GDPR. Our registration is publicly verifiable on Companies House.
A legitimate, tax-filing business — not a throwaway domain with a contact form.
Free, and not paid for with your data
When a product is free, you're usually the product. VoidNote is free — notes, accounts, streams and the vault — and there is nothing to buy. It carries no ads and no trackers, and we don't sell data. Right now we want VoidNote to be used, not paid for.
We have no incentive to harvest secrets, and the design takes the option away: notes are stored as ciphertext, and the key that opens them stays in the link, which we never see. The cryptography doesn't ask you to trust our intentions.
No tracking, no analytics, no fingerprinting
View the page source. There is no Google Analytics. No Facebook Pixel. No Hotjar. No Mixpanel. No tracking scripts of any kind. We don't fingerprint your browser. We don't set third-party cookies.
Our website scores an A+ carbon rating (cleaner than 97% of the web) partly because we don't load dozens of third-party tracking scripts that most sites do.
You can verify this yourself: open DevTools → Network tab → reload the page → filter by third-party domains. You'll find nothing phoning home.
The infrastructure
VoidNote runs entirely on Cloudflare's infrastructure — Workers for compute, D1 for the database and rate limiting, KV for sessions, R2 for vault storage. There's no hidden server in a cupboard.
Cloudflare Workers execute in a sandboxed V8 isolate with no persistent filesystem. The worker
receives and stores ciphertext. For /n/ links it returns ciphertext only;
for older /note/ links it decrypts with the key from the link and returns the text.
The domain is protected by Cloudflare's DDoS protection, and all connections use TLS 1.3. DNS is managed through Cloudflare with DNSSEC enabled.
Still not convinced? Use the SDK directly.
If you don't trust the website at all, don't use it. Use the SDK or CLI instead. The encryption happens in your code, on your machine. You can read every line of the SDK before you run it. Links the SDK and CLI create keep the key in the URL fragment, so the server only ever sees ciphertext.
# Encrypt and send from your terminal — the website is never involved
echo "DATABASE_URL=postgres://..." | voidnote create --views 1
→ https://voidnote.net/n/abc123#e5f6a7b8...
The web interface, the SDK, and the CLI all encrypt the same way and make the same
/n/…#key links, which decrypt on the reader's device.
The short version
Encrypted before upload — notes are stored as ciphertext, without their keys. Links (/n/…#key) are decrypted on the reader's device.
Verifiable in 30 seconds — open DevTools and watch. The create request never contains the plaintext or the key.
Open source — every SDK, every crypto implementation, readable and auditable.
Registered company — registered in England and Wales, subject to UK GDPR, publicly verifiable at Companies House.
No tracking — no analytics, no pixels, no fingerprinting. Check the source.
Free, with nothing to sell — no plans, no ads, no data sales.
Convinced? Sceptical? Either way, the DevTools are right there.