SnapSend
The trust model, explained

Your secret is encrypted before we ever see it.

SnapSend is zero-knowledge by architecture, not by promise. Every secret is encrypted with AES-256-GCM in your browser, the server only ever stores an opaque blob it cannot decrypt.

Five steps

From your keyboard to theirs never in plaintext.

Here's the exact lifecycle of a secret, from the moment you hit "Encrypt" to the moment it burns.

  1. 01

    Your browser generates the key

    When you create a secret, your browser generates a random 256-bit key and IV using the Web Crypto API. No third-party crypto library, no server round-trip, the key is born on your device.

    const key = await crypto
      .subtle.generateKey(
        { name: 'AES-GCM',
          length: 256 }, …)
  2. 02

    Encryption happens locally

    The secret is encrypted in your browser tab with AES-256-GCM. What leaves your device is ciphertext, mathematically unreadable without the key that never left.

    plaintext
    ──encrypt──▶ a91f…c04e
    // only this is sent
  3. 03

    The server stores what it can't read

    The API drops the ciphertext into Redis with a TTL matching your expiry. There's no relational database, no backup trail, no analytics, an opaque blob with a countdown.

    SET secret:8fJq2xVb
      { ciphertext, iv }
    EX 3600 // self-destructs
  4. 04

    The key travels in the URL fragment

    Your share link carries the key after the #. By the URL specification itself, browsers never send fragments to any server, this is a hard guarantee of the web platform, not an app-level promise.

    /s/8fJq2xVb#key=X9dK…
    // fragment stays
    // in the browser
  5. 05

    Read once, then it burns

    The recipient's browser fetches the ciphertext, decrypts it locally, and displays it. A Lua script decrements views and deletes atomically , even two simultaneous readers can't get a second copy. TTL cleans up anything never opened.

    -- atomic burn
    if views < 1 then
      redis.DEL(id)
    end
Anatomy of a link

One URL, two very different halves.

Everything before the # goes to the server. Everything after it never leaves your browser.

https://snapsend.app/s/8fJq2xVb#key=X9dKpL2mQ7ZrTnE4wA1sHcU6oB3vNyGf

The address

Public routing. It tells your browser where the app lives, nothing sensitive here.

The id

A random handle the server uses to look up the ciphertext. Useless on its own, it unlocks nothing.

The key

Lives after the #. Browsers strip fragments from every request, the server can't receive it even by accident.

Zero-knowledge, literally

What our server sees. And what it never can.

The server sees

  • ciphertext an encrypted blob it has no key for
  • iv a public initialization vector, useless without the key
  • expiry & view count housekeeping needed to burn on time
  • a random id the lookup handle in your link's path

The server never sees

  • your plaintext it's encrypted before any request is made
  • the encryption key it exists only in the URL fragment
  • who you are no accounts, no history, no audit trail
  • anything after it burns deletion is atomic and final
Under the hood

Built on boring, proven pieces.

Encryption

Web Crypto API

Native browser crypto , AES-256-GCM with authenticated encryption. No third-party crypto libraries to audit or trust.

Storage

Redis, and nothing else

Native TTL handles expiry with no cron jobs. A Lua script makes burn-on-read atomic under concurrent reads.

Backend

.NET Web API

A deliberately simple N-tier API: three endpoints, per-IP rate limiting, and zero logging of anything secret-adjacent.

Common questions

The fine print, honestly.

Q. Can SnapSend recover a secret if lost?

No, and that's the design. Without your link's key fragment, the ciphertext is unreadable to everyone, including us. Once it burns or expires, it's gone from Redis entirely.

Q. What if two people open the link at once?

The view counter is decremented and the entry deleted in a single atomic Lua script. Exactly the permitted number of views succeed, a race can't produce an extra copy.

Q. Is the QR code as sensitive as the link?

Yes, the QR encodes the full URL, key fragment included. Treat a screenshot of it exactly like the secret itself.

Q. Why should I trust this more than a promise?

Because it isn't a promise. Browsers never transmit URL fragments, that's the web specification. The server can't leak, log, or be subpoenaed for a key it never received.

Share your first secret in under ten seconds.

No account. No install. Nothing left behind.

Zero-knowledge · Burn-on-read · No accounts