Condensed from PROTOCOL.md (the full wire spec). For the product overview see Courier.
Every message is an envelope: a signed, encrypted payload stored on the relay. The relay is a dumb store-and-forward mailbox — it verifies the sender's Ed25519 signature before storing, but cannot read contents.
from is authenticated, not asserted.crypto_box (X25519) sealed to the recipient, with a fresh ephemeral sender key per message.| Endpoint | Purpose |
|---|---|
POST /v1/send |
Submit a signed envelope |
GET /v1/inbox |
Fetch your envelopes |
GET /v1/inbox/subscribe |
Long-poll for new envelopes |
POST /v1/keys, GET /v1/keys/{address} |
Key directory (publish/lookup encryption keys) |
POST /v1/report |
Spam/abuse reports |
POST /v1/blobs, GET /v1/blobs/{id} |
Blob store (attachments) |
POST /v1/groups/control |
Group messaging control |
GET /v1/health |
Relay health + version |
Authorization: every request is authenticated by the envelope/request signature — there are no passwords or API tokens.
courier fs) for per-conversation sessions.courier rotate publishes a new encryption key to the directory; the address (signing key) never changes.The complete wire format, canonical forms, payload versions, and threat model live in PROTOCOL.md in the repo. Start there when implementing a new client.