Reflecto’s product promise is that the server is a dumb relay — it routes opaque encrypted blobs between your paired devices and never sees the plaintext. The public API has a single scoped carve-out:Documentation Index
Fetch the complete documentation index at: https://docs.reflecto.dev/llms.txt
Use this file to discover all available pages before exploring further.
POST /v1/send
accepts plaintext over TLS so the server can encrypt-and-forward to every
recipient device. This page is the honest accounting of what changes for
callers.
What the server sees on /v1/send
When you call POST /v1/send, the plaintext envelope exists in server RAM
for the duration of the encrypt-and-forward operation. The server:
- Builds the envelope (
{ type, payload, source }). - Looks up each recipient device’s stored X25519 public key.
- For each recipient: derives a shared secret from the server’s private key
and the recipient’s public key, generates a fresh 24-byte nonce, encrypts
with
nacl.secretbox. - Writes the encrypted blob to the per-device Redis queue.
- Discards the plaintext envelope.
token_id, user_id, and an error code — never the
payload.
What the server cannot see
| Visible to server | Not visible to server |
|---|---|
user_id (resolved from your token) | Anything you send between your own devices via mirroring (encrypted on the source device). |
token_id, label | Shared secrets, device private keys. |
| Target device list, timestamps, source IP | Long-term storage of any /v1/send payload (none is persisted). |
Wire format
Recipients decrypt each envelope as:nacl.box.before()
in TweetNaCl (and crypto_box_beforenm in libsodium) does the X25519 +
HSalsa20 in one call and returns the secretbox key.
nacl.secretbox is authenticated encryption — a successful open proves the
ciphertext was produced by an entity holding the server’s private key (i.e.
the server itself, in normal operation). A failing open means the envelope
was tampered with or misrouted; the device drops it. There is no separate
signature.
Server keypair
The server holds a single X25519 keypair generated at bootstrap and distributed to devices at pair time (via/v1/pair/confirm for Android,
/v1/devices/add-extension for the extension). Devices store the server
pubkey alongside other paired-device pubkeys, marked type: "server".
There is no runtime backfill endpoint — devices that paired before the
public-API rollout must re-pair to receive the key. Server keypair rotation
is deferred to V2.
What this means for you
- Treat
/v1/sendpayloads the way you’d treat any HTTPS POST body. The privacy boundary is “no long-term server visibility,” not “no momentary server visibility.” - Don’t put secrets in notification text that you wouldn’t put in any HTTPS request. The server doesn’t log it, but the trust model isn’t zero-knowledge.
- Mirroring traffic stays end-to-end encrypted. Notifications captured
on your phone by
NotificationListenerServiceare encrypted on-device before they hit the wire; the server never sees their plaintext.