Direct Messages API¶
Older endpoint notes
Rendered from ProjectInfo/api-docs/api/dm.md on docs/encryption-modes-spec. These notes predate the REST API reference, which is canonical wherever the two overlap. They are published because they still cover endpoints the reference does not yet document — check shapes against the reference and the spec errata.
DM messages are true E2EE — server stores ciphertext blobs only, never decrypts.
See e2ee.md for the full encryption protocol.
All endpoints require Authorization: Bearer <token>.
POST /api/dm¶
Open or find an existing 1:1 DM channel. Idempotent.
Request:
Response 201 (new) or 200 (existing): DMChannel
Errors: 400 (self-DM)
GET /api/dm¶
List all DM channels the authenticated user belongs to, ordered by most recently active.
Response 200: Array of DMChannel
GET /api/dm/{channelID}¶
Fetch a single DM channel.
Response 200: DMChannel
Errors: 403 (not a member)
DELETE /api/dm/{channelID}¶
Leave a DM channel. Channel + messages are retained for other participant.
Response 204
POST /api/dm/{channelID}/messages¶
Send an E2EE DM message.
Request:
{
"ciphertext": "base64",
"ratchet_header": "base64",
"x3dh_header": "base64 (first message in a session only, omit otherwise)",
"device_ciphertexts": [
{ "device_id": "string", "ciphertext": "base64" }
],
"reply_to_id": "uuid (optional)"
}
ciphertext— Double Ratchet encrypted message payloadratchet_header— current ratchet public key + chain/message indicesx3dh_header— only on first message (includesephemeral_key,signed_prekey_id,one_time_prekey_id,sender_device_id)device_ciphertexts— one entry per recipient device AND per sender's other devices
Response 201: DMMessage
Errors: 400 (empty ciphertext), 403 (not a member)
Real-time: fires MESSAGE_CREATE on channel.<channelID>.MESSAGE_CREATE.
GET /api/dm/{channelID}/messages?limit=50&before={messageID}¶
Fetch DM message history. Each message includes all device_ciphertexts — client finds its own device_id to decrypt.
Query params:
- limit: 1–100, default 50
- before: cursor UUID (oldest message from previous page)
Response 200: Array of DMMessage, newest first.
DELETE /api/dm/{channelID}/messages/{messageID}¶
Soft-delete a DM message. Only the original sender.
Response 204
Errors: 403 (not sender), 404 (not found)
Real-time: fires MESSAGE_DELETE on the channel subject.