All endpoints accept POST with Content-Type: application/json. Authentication is via authToken in the request body, stripped before storage.
The name field on every User request body must be sent empty (""). User nicknames never travel as a plain field — they're carried only inside the encrypted payloads of messages, so the server cannot index or read them.
Register a new user. No request body required. Returns a generated user ID and an auth token.
{
"object": "User",
"userId": "<generated-hex-id>",
"name": "",
"authToken": "<generated-token>"
}
Generate a new group ID. Caller must authenticate.
{
"object": "User",
"userId": "<userId>",
"name": "",
"authToken": "<authToken>"
}
{
"object": "Group",
"groupId": "<generated-group-id>",
"name": ""
}
Poll for pending notifications (friend requests, friend responses, group invites, direct messages) since a given timestamp.
{
"object": "User",
"userId": "<userId>",
"name": "",
"authToken": "<authToken>",
"lastMessageTimestamp": 1712345678000
}
{
"object": "Notifications",
"friendRequests": [
{
"object": "FriendRequest",
"fromUserId": "<id>",
"toUserId": "<id>",
"protocol": "DH_AND_AES",
"cryptoData": "<base64-key-exchange>",
"timestamp": 1712345678000
}
],
"friendResponses": [
{
"object": "FriendResponse",
"fromUserId": "<id>",
"toUserId": "<id>",
"cryptoData": "<base64-key-exchange>",
"timestamp": 1712345678000
}
],
"groupInvites": [
{
"object": "GroupInvite",
"fromUserId": "<id>",
"toUserId": "<id>",
"groupId": "<groupId>",
"algorithm": "AES_256",
"cryptoData": "<encrypted-group-key>",
"timestamp": 1712345678000
}
],
"messages": [
{
"object": "SendMessage",
"fromUserId": "<id>",
"toId": "<id>",
"encContent": "<encrypted-message>",
"timestamp": 1712345678000
}
]
}
Send a friend request. Initiates the key exchange by delivering the caller's Diffie-Hellman public key to the target user's notification queue.
{
"object": "FriendRequest",
"fromUserId": "<userId>",
"authToken": "<authToken>",
"toUserId": "<targetUserId>",
"protocol": "DH_AND_AES",
"cryptoData": "<base64-dh-public-key>"
}
Reply to a friend request. Completes the key exchange by delivering the responder's Diffie-Hellman public key to the original sender.
{
"object": "FriendResponse",
"fromUserId": "<userId>",
"authToken": "<authToken>",
"toUserId": "<targetUserId>",
"cryptoData": "<base64-dh-public-key>"
}
Send an encrypted direct message to another user.
{
"object": "SendMessage",
"fromUserId": "<userId>",
"authToken": "<authToken>",
"toId": "<targetUserId>",
"encContent": "<encrypted-message-payload>"
}
Invite a user to a group. Delivers the AES-256 encrypted group key to the recipient's notification queue. Both the target user and the group must already exist.
{
"object": "GroupInvite",
"fromUserId": "<userId>",
"authToken": "<authToken>",
"toUserId": "<targetUserId>",
"groupId": "<groupId>",
"algorithm": "AES_256",
"cryptoData": "<encrypted-group-key>"
}
Send an encrypted message to a group. Uses the same schema as /postmsg with toId set to the group ID.
{
"object": "SendMessage",
"fromUserId": "<userId>",
"authToken": "<authToken>",
"toId": "<groupId>",
"encContent": "<encrypted-message-payload>"
}
Poll for new messages in a single group since a given timestamp.
{
"object": "PollGroup",
"userId": "<userId>",
"authToken": "<authToken>",
"groupId": "<groupId>",
"lastMessageTimestamp": 1712345678000
}
{
"object": "GroupNotifications",
"messages": [
{
"object": "SendMessage",
"fromUserId": "<id>",
"toId": "<groupId>",
"encContent": "<encrypted-message>",
"timestamp": 1712345678000
}
]
}
Poll for new messages across multiple groups at once since a given timestamp.
{
"object": "PollGroups",
"userId": "<userId>",
"authToken": "<authToken>",
"groupIds": ["<groupId1>", "<groupId2>"],
"lastMessageTimestamp": 1712345678000
}
Same GroupNotifications schema as /pollgroup.
Long-poll across multiple groups. Blocks server-side until a new message arrives for the user in any of the listed groups, then returns immediately.
{
"object": "PollGroups",
"userId": "<userId>",
"authToken": "<authToken>",
"groupIds": ["<groupId1>", "<groupId2>"],
"lastMessageTimestamp": 1712345678000
}
Plain text: the group ID that received a new message, or empty string if the wait timed out.
| Status | Meaning |
|---|---|
| 400 | Malformed or missing required fields |
| 404 | Target user or group does not exist |
| 429 | Rate limited — back off and retry |
| 500 | Internal server error (plain text exception message) |