Mail API

Endpoints for the PQC-encrypted mail system. Mail uses the same ML-KEM-768 encryption as the messenger but adds subject lines, folders, threading, and a name registry.

Name Registry

Register a Name

POST /api/names/register
Content-Type: application/json

Register a human-readable email address (e.g., alice@rouge.quant).

{
  "name": "alice",
  "publicKey": "your-signing-public-key-hex",
  "encPublicKey": "your-ml-kem768-public-key-hex"
}

Response

{
  "success": true,
  "address": "alice@rouge.quant"
}

Error

{
  "success": false,
  "error": "Name already taken"
}

Lookup a Name

GET /api/names/lookup?name=alice

Response

{
  "name": "alice",
  "publicKey": "abc123...",
  "encPublicKey": "def456..."
}

Reverse Lookup (Public Key to Name)

GET /api/names/reverse?publicKey=abc123...

Response

{
  "name": "alice",
  "publicKey": "abc123..."
}

Send Mail

POST /api/mail/send
Content-Type: application/json

Request Body

{
  "from": "alice",
  "fromPublicKey": "sender-pub-hex",
  "to": "bob",
  "toPublicKey": "recipient-pub-hex",
  "senderEncrypted": "base64-encrypted-for-sender",
  "recipientEncrypted": "base64-encrypted-for-recipient",
  "replyToId": null
}

The senderEncrypted and recipientEncrypted fields contain the encrypted subject and body. Both sender and recipient get their own copy, just like the messenger.

Set replyToId to the ID of the mail being replied to, enabling threading.

Response

{
  "success": true,
  "id": "mail-uuid"
}

Get Inbox

GET /api/mail/inbox?publicKey=your-pub-hex

Response

{
  "mail": [
    {
      "id": "mail-uuid",
      "from": "alice",
      "fromPublicKey": "abc...",
      "to": "bob",
      "toPublicKey": "def...",
      "encrypted": "base64-ciphertext",
      "timestamp": 1706745600000,
      "read": false,
      "replyToId": null
    }
  ]
}

Get Sent Mail

GET /api/mail/sent?publicKey=your-pub-hex

Same response format as inbox, but returns mail you sent.


Get Single Mail

GET /api/mail/message/:id?publicKey=your-pub-hex

Mark as Read

POST /api/mail/read
Content-Type: application/json
{
  "id": "mail-uuid"
}

Move to Trash

POST /api/mail/move
Content-Type: application/json
{
  "id": "mail-uuid",
  "folder": "trash"
}

Get Trash

GET /api/mail/trash?publicKey=your-pub-hex

Delete Mail

DELETE /api/mail/:id

Permanently deletes a mail item.


Email Domains

DomainPlatform
@rouge.quantWebsite and browser extensions
@qwalla.mailQWalla mobile app (future)

Threading

Mail threading is handled client-side by following the replyToId chain. When viewing a mail, the client:

  1. Fetches both inbox and sent mail
  2. Walks the replyToId chain to build the thread
  3. Displays messages in chronological order
  4. Collapses older messages, expands the latest two

Encryption

Mail uses the same encryption as the messenger:

  1. Look up recipient's ML-KEM-768 public key via Name Registry
  2. Encapsulate a shared secret
  3. Derive AES-256 key via HKDF
  4. Encrypt subject + body with AES-GCM
  5. Create separate ciphertext for sender and recipient
  6. Server stores both encrypted copies