The API

Open, anonymous, no auth. Every note is AES-256-GCM encrypted with a key the server never stores — see how it works for the full model.

Body is the raw payload — text or file bytes. Everything else is headers, so it works cleanly with curl --data-binary.

Content-TypeReal MIME type of the payload
X-PasswordOptional password; required again to read
X-ViewsMax number of reads (default 1)
X-TTL-MinutesExpire after N minutes regardless of views
X-Allowed-IPExact IP, IPv4 CIDR, or comma-separated list
X-FilenameOriginal filename, for downloads
X-Encrypted: clientPayload is already encrypted by the caller; stored opaquely
curl -X POST https://api.whisper.beer/notes \
  -H "Content-Type: application/pdf" \
  -H "X-Filename: contract.pdf" \
  -H "X-Password: hunter2" \
  -H "X-Views: 5" \
  -H "X-TTL-Minutes: 60" \
  --data-binary @contract.pdf

Each successful read burns one view. A wrong key/password or a blocked IP never consumes a view, so a guesser can't burn the real recipient's read.

curl "https://api.whisper.beer/notes/ID?key=KEY" -o downloaded_file
curl "https://api.whisper.beer/notes/ID?key=KEY" -H "X-Password: hunter2"

The key never has to travel to the server on read. Response headers carry the crypto metadata needed to decrypt offline.

curl -D headers.txt -o note.enc "https://api.whisper.beer/notes/ID"
X-Views-RemainingViews left after this read
X-Algaes-256-gcm
X-Iv, X-Auth-TagBase64url GCM parameters, for local decryption
X-SaltPresent if a password was set; needed to re-derive the key
  • IP allowlist supports exact match or IPv4 CIDR — no IPv6 CIDR yet.
  • No auth, no rate limiting — it's anonymous by design.
  • Request/response bodies are capped around 4MB per note or file.
← Back to overview