Introduction
This API documentation outlines a messaging platform with end-to-end encryption (E2EE), user management, group capabilities, communities, statuses, and media handling. It also incorporates analytics to track user activity. The core focus is on secure communication, emphasizing encrypted content and metadata handling. A crucial aspect of this API is its integration with Socket.io for real-time updates.
General Notes:
- End-to-End Encryption (E2EE): The API extensively uses E2EE. Messages are encrypted before being sent to the server. The server does not have access to the decrypted message content. Pay close attention to the handling of encryption keys, initialization vectors (IVs), and the specific encryption algorithms used (not explicitly stated here, but likely AES or similar).
- Socket.io Integration: The API uses Socket.io for real-time updates, such as new messages, typing indicators, message reactions, and status updates. You'll need a Socket.io client to receive these updates. The documentation indicates what events are emitted and to whom.
- User IDs and Other IDs: User IDs, message IDs, group IDs, community IDs, and channel IDs are all represented as strings. These are presumably generated by the backend.
- Date and Time: Dates and times are generally formatted according to ISO 8601 (e.g.,
2025-04-12T11:56:12.043Z). - Error Handling: This documentation doesn't explicitly describe error responses. In a real-world API, you'd expect to see error codes and messages returned in case of issues (e.g., invalid input, user not found, permission denied). Assume that a
success: falseresponse indicates an error. - Authentication: This API documentation lacks authentication and authorization mechanisms. So these are the things which needs to be taken care of.
1. API Health
- Endpoint:
GET /api/health - Description: Checks the health of the API. Useful for monitoring and troubleshooting.
- Request:
GET /api/health - Response:
{ "success": true, "message": "API is healthy" }
2. User Management
-
2.1 Register a New User
- Endpoint:
POST /api/users/register - Description: Creates a new user account.
- Request Body (JSON):
{ "username": "Ishu", "deviceId": "absetnt233434", "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArFcZpZfQYQ/5KRb/c8UtNYVmGrGJt/hKbD7hlBy0Cukky5wW4mifVKzJ7TyHTdpxbpY/se6d5FaBhA+agORl9TiRdnfS/+GQTLUv/ey7u+rHlvrEZGc1i31ByculGWIptaQOS2VvMlZyCqBHk7UEPK7W6lODVi4YQ2kFNs0jRNkHtXl0a0He7XiYQlZU5bsGdu10/9mVm3krW6EAyDvjiAvtSjCFy1q6Blr0VOaZkZcIMBxw45uS8TH8UIAm9E4Y0pNbCCYBmuw0SvjQnPohLVJKnvY2HxZXUfWxeTLZ6DKCAJN14flGasHFvGQ/L8wE1RDy6VslGlcl4xHCyseyEQIDAQAB" }username: The user's desired username.deviceId: A unique identifier for the user's device. This is very important for E2EE because it can be used to identify device-specific keys.publicKey: The user's public key, essential for E2EE. This key is used by other users to encrypt messages for this user. The format should be PEM encoded.
- Response:
{ "success": true, "data": { "userId": "67fa4e122f209f597a5fbd3f", "username": "Ishu", "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArFcZpZfQYQ/5KRb/c8UtNYVmGrGJt/hKbD7hlBy0Cukky5wW4mifVKzJ7TyHTdpxbpY/se6d5FaBhA+agORl9TiRdnfS/+GQTLUv/ey7u+rHlvrEZGc1i31ByculGWIptaQOS2VvMlZyCqBHk7UEPK7W6lODVi4YQ2kFNs0jRNkHtXl0a0He7XiYQlZU5bsGdu10/9mVm3krW6EAyDvjiAvtSjCFy1q6Blr0VOaZkZcIMBxw45uS8TH8UIAm9E4Y0pNbCCYBmuw0SvjQnPohLVJKnvY2HxZXUfWxeTLZ6DKCAJN14flGasHFvGQ/L8wE1RDy6VslGlcl4xHCyseyEQIDAQAB" } }userId: The unique ID assigned to the new user. Store this!username: The username.publicKey: The user's public key (echoed back).
- Endpoint:
-
2.2 Block a User
- Endpoint:
POST /api/users/block - Description: Blocks a user, preventing them from sending messages to the blocking user.
- Request Body (JSON):
{ "userId": "67f640e6b2dffb1086532c42", "blockedUserId": "67f640afb2dffb1086532c3f" }userId: The ID of the user initiating the block.blockedUserId: The ID of the user being blocked.
- Response:
{ "success": true, "message": "User blocked successfully" }
- Endpoint:
-
2.3 Unblock a User
- Endpoint:
POST /api/users/unblock - Description: Unblocks a previously blocked user.
- Request Body (JSON):
{ "userId": "67f640e6b2dffb1086532c42", "blockedUserId": "67f640afb2dffb1086532c3f" }userId: The ID of the user initiating the unblock.blockedUserId: The ID of the user being unblocked.
- Response:
{ "success": true, "message": "User unblocked successfully" }
- Endpoint:
-
2.4 Mute a User
- Endpoint:
POST /api/users/mute - Description: Mutes a user for a specific duration. Muted users' messages won't be displayed/notified to the muting user.
- Request Body (JSON):
{ "userId": "67f640afb2dffb1086532c3f", "mutedUserId": "67f640e6b2dffb1086532c42", "duration": 86400 }userId: The ID of the user initiating the mute.mutedUserId: The ID of the user being muted.duration: The mute duration in seconds (e.g., 86400 seconds = 1 day).
- Response:
{ "success": true, "message": "User muted successfully", "expiresIn": 86400 }expiresIn: The mute duration in seconds (echoed back).
- Endpoint:
3. Direct Messaging
-
3.1 Send a Message
- Endpoint:
POST /api/messages/send - Description: Sends a direct message to another user.
- Request Body (JSON):
{ "senderId": "67f640afb2dffb1086532c3f", "recipientId": "67f640e6b2dffb1086532c42", "encryptedContent": "{\"message\":\"wm0dZJ+UlG1KB0AEwvKVd1cQiVwnRabWUH2/QaC86x8=\",\"key\":\"cc+rpjCg++FSWPToUk7qZRQZ9mhP6SlEIfSiesStKd0skKqTe12I2byoTnkAH8AbdZk41B/2fXd0m+eb+mtfNWZ11Rm1OrMGxd/IbHxMcE7ch3YuWsedInpnAvPavPUFCF/1i4m/oj10Id/m09gvObGCwXW+gQluhqJrCKTraTsYhYbNCArvnVl62oN7LW9E7ss68obp+6yVAzQrrlZYBipK6UsvwSFvnfZE8V+TY7UElJGcFgPMYKngEg6RvygWzZFMD9mj5He8Jea4jYx4/kcD1tJfOov14ToppEAB7doEzoKrggnQGB180dbmLBK4jKoeVuuTFiWdltY6FOIUcA==\",\"iv\":\"uTiFPIa04CDXI4gM3sEAVA==\"}", "type": "text", "mediaId": "", "replyToId": "" }senderId: The ID of the user sending the message.recipientId: The ID of the user receiving the message.encryptedContent: CRITICAL: This is a JSON string representing the encrypted message content. It must include the encrypted message, the encryption key (encrypted with the recipient's public key), and the initialization vector (IV).- The
messagefield contains the actually encrypted payload. - The
keycontains encrypted AES key using recipient's public key for E2EE - The
ivis the initialization vector to be used for AES decryption
- The
type: The message type (e.g., "text", "image", "video").mediaId: If the message contains media, the ID of the media file (uploaded separately via/api/media/upload). Leave empty if no media.replyToId: If this is a reply to another message, the ID of the message being replied to. Leave empty if not a reply.
- Response:
{ "success": true, "data": { "messageId": "msg_4055d0535aeb4fcaa8854b9a1bb13412", "status": "sent", "sentAt": "2025-04-12T11:56:12.043Z" } }messageId: The unique ID of the message. Store this!status: The message status (e.g., "sent").sentAt: The timestamp when the message was sent.
- Socket.io Event: Upon successful sending, the server emits a
new_messageevent to the recipient.io.to(recipientId).emit("new_message", { messageId, senderId, type, mediaId, replyToId, sentAt: message.sentAt, });
- This event provides metadata about the new message, but not the encrypted content itself. The client uses this event to fetch the message (if needed) and decrypt it using its stored keys.
- Endpoint:
-
3.2 Get Chat History
- Endpoint:
GET /api/messages/:userId/:recipientId - Description: Retrieves the chat history between two users.
- Request:
GET /api/messages/67f640afb2dffb1086532c3f/67f640e6b2dffb1086532c42userId: The ID of the requesting user.recipientId: The ID of the other user in the chat.
- Response:
{ "success": true, "data": [ { "messageId": "msg_62c76b5cf66345febaef1a0b2d246588", "senderId": "67f640afb2dffb1086532c3f", "recipientId": "67f640e6b2dffb1086532c42", "content": "{\"message\":\"wm0dZJ+UlG1KB0AEwvKVd1cQiVwnRabWUH2/QaC86x8=\",\"key\":\"cc+rpjCg++FSWPToUk7qZRQZ9mhP6SlEIfSiesStKd0skKqTe12I2byoTnkAH8AbdZk41B/2fXd0m+eb+mtfNWZ11Rm1OrMGxd/IbHxMcE7ch3YuWsedInpnAvPavPUFCF/1i4m/oj10Id/m09gvObGCwXW+gQluhqJrCKTraTsYhYbNCArvnVl62oN7LW9E7ss68obp+6yVAzQrrlZYBipK6UsvwSFvnfZE8V+TY7UElJGcFgPMYKngEg6RvygWzZFMD9mj5He8Jea4jYx4/kcD1tJfOov14ToppEAB7doEzoKrggnQGB180dbmLBK4jKoeVuuTFiWdltY6FOIUcA==\",\"iv\":\"uTiFPIa04CDXI4gM3sEAVA==\"}", "contentHash": "68697162b8769635aacc7374549ffdeda06911316fa44b6f9f65cdd342c17ab8", "type": "text", "mediaId": null, "replyToId": "msg_51677004832949ef93a90977d103c862", "status": "sent", "sentAt": "2025-04-09T10:20:09.472Z", "deliveredAt": null, "seenAt": null }, { "messageId": "msg_e27f7b2e47e34d08aa37e596017123fd", "senderId": "67f640afb2dffb1086532c3f", "recipientId": "67f640e6b2dffb1086532c42", "content": "{\"message\":\"Wr6A8GbZ7h8FKHDI+sOAO3BTXgv8cUItj+D5YwV/h6mYWzgAe3UCEFyBBVRHIHYG\",\"key\":\"IpuM8b2tftY7GVrk4JZAhpOhY4ikicIckA0udFCbAQsJnyLB7iNpt5gEtcizOTxhrjjnbM8suLjWluxLJLSNpuyXz73cDkOpt7LfL64K3L5QfwL5xwdn8Bqk3xSwKC2Xy1T/QvjXA+Xo+bas1LgH4KjdonoypdKDb/8BBcCu77ObloABZjLeXBpAn2wABbP0BZfHBHtLHOSjmqyCHaVCnc+/M6e3pliEeXlymrZ5bPm625Prr1qkD2QxDIXsr0GS8UR7xpMin02wXB10FYnZj6pjx60/NHsx0OfH34PFtVt4FuFTIm9ErqRdKs6a43ZWgSZq3OZ1A56JBKN1sD51tA==\",\"iv\":\"SABSua3l4mvt+iHPd5TM9Q==\"}", "contentHash": "51408d0350ec851bf41daed6f63fac6c68992f37da77b43b99306cad378a746c", "type": "text", "mediaId": "", "replyToId": "", "status": "sent", "sentAt": "2025-04-09T10:09:03.655Z", "deliveredAt": null, "seenAt": null } ] }- The
dataarray contains an array of message objects. - Each message object includes
messageId,senderId,recipientId, thecontent(encrypted!),type,mediaId,replyToId,status, and timestamps. contentHash: Hash of the encrypted content. Used to verify content integrity.deliveredAt,seenAt: Timestamps indicating when the message was delivered and seen by the recipient.
- The
- Endpoint:
-
3.3 Send Typing Indicator
- Endpoint:
POST /api/messages/typing - Description: Sends a typing indicator to the recipient.
- Request Body (JSON):
{ "senderId": "67f640afb2dffb1086532c3f", "recipientId": "67f640e6b2dffb1086532c42" }senderId: The ID of the user who is typing.recipientId: The ID of the user who will receive the typing indicator.
- Response:
{ "success": true, "message": "Typing indicator sent" } - Socket.io Event: The server emits a
typing_indicatorevent to the recipient.io.to(recipientId).emit("typing_indicator", { senderId, isTyping, timestamp, });
senderId: The ID of the user who is typing.isTyping: A boolean indicating whether the user is typing (true) or has stopped typing (false). You'd typically send afalsevalue after a certain period of inactivity.timestamp: The timestamp of the event.
- Endpoint:
-
3.4 Reply to a Message
- Endpoint:
POST /api/messages/reply - Description: Sends a reply to an existing message.
- Request Body (JSON):
{ "replyToId": "msg_51677004832949ef93a90977d103c862", "encryptedContent": "{\"message\":\"wm0dZJ+UlG1KB0AEwvKVd1cQiVwnRabWUH2/QaC86x8=\",\"key\":\"cc+rpjCg++FSWPToUk7qZRQZ9mhP6SlEIfSiesStKd0skKqTe12I2byoTnkAH8AbdZk41B/2fXd0m+eb+mtfNWZ11Rm1OrMGxd/IbHxMcE7ch3YuWsedInpnAvPavPUFCF/1i4m/oj10Id/m09gvObGCwXW+gQluhqJrCKTraTsYhYbNCArvnVl62oN7LW9E7ss68obp+6yVAzQrrlZYBipK6UsvwSFvnfZE8V+TY7UElJGcFgPMYKngEg6RvygWzZFMD9mj5He8Jea4jYx4/kcD1tJfOov14ToppEAB7doEzoKrggnQGB180dbmLBK4jKoeVuuTFiWdltY6FOIUcA==\",\"iv\":\"uTiFPIa04CDXI4gM3sEAVA==\"}", "senderId": "67f640afb2dffb1086532c3f", "recipientId": "67f640e6b2dffb1086532c42" }replyToId: The ID of the message being replied to.encryptedContent: The encrypted content of the reply message (same format as in/api/messages/send).senderId: The ID of the user sending the reply.recipientId: The ID of the user receiving the reply.
- Response:
{ "success": true, "data": { "messageId": "msg_5a23c2352f45439da58a9f12cf0b7f60", "status": "sent", "sentAt": "2025-04-10T16:20:04.323Z" } } - Socket.io Event: The server emits a
new_messageevent to the recipient (same as when sending a regular message). The recipient knows it's a reply because thereplyToIdfield is present in the message metadata.
- Endpoint:
-
3.5 React to a Message
- Endpoint:
POST /api/messages/react - Description: Adds a reaction (e.g., emoji) to a message.
- Request Body (JSON):
{ "messageId": "msg_51677004832949ef93a90977d103c862", "reaction": "??", "userId": "67f640afb2dffb1086532c3f" }messageId: The ID of the message being reacted to.reaction: The reaction (e.g., an emoji string).userId: The ID of the user who is reacting.
- Response:
{ "success": true, "data": { "messageId": "msg_51677004832949ef93a90977d103c862", "reaction": "??" } } - Socket.io Event: The server emits a
message_reactionevent to the recipient.io.to(message.recipientId.toString()).emit("message_reaction", { messageId, userId, reaction, });
messageId: The ID of the message being reacted to.userId: The ID of the user who reacted.reaction: The reaction that was added.
- Endpoint:
-
3.6 Delete a Message
- Endpoint:
POST /api/messages/delete - Description: Deletes a message.
- Request Body (JSON):
{ "messageId": "f6a7b8c9-d0e1-2345-6789-0abcdef01234", "userId": "a1b2c3d4-e5f6-7890-1234-567890abcdef", "deleteForEveryone": false }messageId: The ID of the message to delete.userId: The ID of the user requesting the deletion. This is likely to verify that the user has permission to delete the message (e.g., they are the sender).deleteForEveryone: A boolean indicating whether to delete the message for everyone (both sender and recipient) or just for the user. Iftrue, the recipient's client should also remove the message from their UI.
- Response:
{ "success": true, "message": "Message deleted successfully", "deleteForEveryone": false } - Socket.io Event: The server emits a
message_deletedevent to the recipient ifdeleteForEveryoneis true.io.to(message.recipientId.toString()).emit("message_deleted", { messageId, deleteForEveryone: true, });
messageId: The ID of the deleted message.deleteForEveryone: Indicates whether the message was deleted for everyone.
- Endpoint:
-
3.7 Schedule a Message
- Endpoint:
POST /api/messages/schedule - Description: Schedules a message to be sent at a later time.
- Request Body (JSON): Same as
/api/messages/send.{ "senderId": "67f640afb2dffb1086532c3f", "recipientId": "67f640e6b2dffb1086532c42", "encryptedContent": "{\"message\":\"wm0dZJ+UlG1KB0AEwvKVd1cQiVwnRabWUH2/QaC86x8=\",\"key\":\"cc+rpjCg++FSWPToUk7qZRQZ9mhP6SlEIfSiesStKd0skKqTe12I2byoTnkAH8AbdZk41B/2fXd0m+eb+mtfNWZ11Rm1OrMGxd/IbHxMcE7ch3YuWsedInpnAvPavPUFCF/1i4m/oj10Id/m09gvObGCwXW+gQluhqJrCKTraTsYhYbNCArvnVl62oN7LW9E7ss68obp+6yVAzQrrlZYBipK6UsvwSFvnfZE8V+TY7UElJGcFgPMYKngEg6RvygWzZFMD9mj5He8Jea4jYx4/kcD1tJfOov14ToppEAB7doEzoKrggnQGB180dbmLBK4jKoeVuuTFiWdltY6FOIUcA==\",\"iv\":\"uTiFPIa04CDXI4gM3sEAVA==\"}", "type": "text", "mediaId": "", "replyToId": "" } - Response:
{ "success": true, "data": { "messageId": "msg_ca61e0734c6942b2abb4ff488e89f876", "status": "sent", "sentAt": "2025-04-12T12:22:01.055Z" } }- The response is similiar to the
/api/messages/send.
- The response is similiar to the
- Socket.io Event: When the scheduled time arrives, the server emits a
new_messageevent to the recipient, just as if the message were sent immediately.
- Endpoint:
-
3.8 Update Message Status
- Endpoint:
POST /api/status - Description: Updates the status of a message (e.g., "delivered", "seen").
- Request Body (JSON):
{ "userId": "value", "messageId": "value", "status": "seen" }userId: The ID of the user updating the status (typically the recipient).messageId: The ID of the message whose status is being updated.status: The new status (e.g., "delivered", "seen").
- Response:
{ "success": true, "data": { "messageId": "msg_51677004832949ef93a90977d103c862", "status": "seen", "updatedAt": "2025-04-10T16:32:03.081Z" } }updatedAt: The timestamp when the status was updated.
- Socket.io Event: The server emits a
message_status_updateevent to the sender.io.to(message.senderId.toString()).emit("message_status_update", { messageId, status, timestamp: new Date(), });
messageId: The ID of the message.status: The new status of the message.timestamp: The timestamp of the update.
- Endpoint:
-
3.9 Get Message Status
- Endpoint:
GET /api/status/:messageId - Description: Retrieves the status of a specific message.
- Request:
GET /api/status/msg_51677004832949ef93a90977d103c862messageId: The ID of the message.
- Response:
{ "success": true, "data": { "messageId": "msg_51677004832949ef93a90977d103c862", "status": "seen", "sentAt": "2025-04-09T09:43:23.439Z", "deliveredAt": null, "seenAt": "2025-04-10T16:32:03.080Z" } }- Includes
sentAt,deliveredAt, andseenAttimestamps, providing a history of the message's status.
- Includes
- Endpoint:
**4. Group Management **
-
4.1 Create a New Group
- Response:
{ "success": true, "data": { "groupId": "group_0fe71c5d810c4b2aa03b65c17b96f65c", "name": "DishIs Technologies", "description": "Group for DIT members", "createdBy": "67f640e6b2dffb1086532c42", "membersCount": 2, "createdAt": "2025-04-10T16:38:09.718Z" } }groupId: The unique ID of the new group. Store this!name: The name of the group.description: The group description.createdBy: The ID of the user who created the group.membersCount: The initial number of members in the group.createdAt: The timestamp when the group was created.
- Response:
-
4.2 Get Group Details
- Endpoint:
GET /api/groups/:groupId - Description: Retrieves the details of a specific group.
- Request:
GET /api/groups/group_0fe71c5d810c4b2aa03b65c17b96f65cgroupId: The ID of the group.
- Response:
{ "success": true, "data": { "groupId": "group_0fe71c5d810c4b2aa03b65c17b96f65c", "name": "DishIs Technologies", "description": "Group for DIT members", "createdBy": "67f640e6b2dffb1086532c42", "membersCount": 0, "createdAt": "2025-04-10T16:38:09.738Z" } }- The response contains the same information as the group creation response.
- Endpoint:
-
4.3 Add Members to a Group
- Endpoint:
POST /api/groups/members/add - Description: Adds members to an existing group.
- Request Body (JSON):
{ "userId": "67f640afb2dffb1086532c3f", "groupId": "group_51677004832949ef93a90977d103c862", "members": [ "67f640e6b2dffb1086532c42" ] }userId: The ID of the user initiating the member addition (must have permission).groupId: The ID of the group.members: An array of user IDs to add to the group.
- Response:
{ "success": true, "message": "Added 1 new members to the group", "data": { "groupId": "group_0fe71c5d810c4b2aa03b65c17b96f65c", "newMembers": [ "67f6476eb2dffb1086532c52" ] } }newMembers: An array of the user IDs that were successfully added.
- Endpoint:
-
4.4 Remove a Member from a Group
- Endpoint:
POST /api/groups/members/remove - Description: Removes a member from an existing group.
- Request Body (JSON):
{ "userId": "67f640e6b2dffb1086532c42", "groupId": "group_0fe71c5d810c4b2aa03b65c17b96f65c", "memberId": "67f6476eb2dffb1086532c52" }userId: The ID of the user initiating the member removal (must have permission).groupId: The ID of the group.memberId: The ID of the user to remove from the group.
- Response:
{ "success": true, "message": "Member removed from the group", "data": { "groupId": "group_0fe71c5d810c4b2aa03b65c17b96f65c", "memberId": "67f6476eb2dffb1086532c52" } }memberId: The ID of the user that was removed.
- Endpoint:
-
4.5 Update Group Settings
- Endpoint:
POST /api/groups/settings - Description: Updates the settings of an existing group.
- Request Body (JSON):
{ "userId": "value", "groupId": "value", "settings": { "onlyAdminsCanSend": false, "onlyAdminsCanAddMembers": true } }userId: The ID of the user initiating the settings update (must have permission).groupId: The ID of the group.settings: An object containing the settings to update.onlyAdminsCanSend: A boolean indicating whether only admins can send messages in the group.onlyAdminsCanAddMembers: A boolean indicating whether only admins can add members to the group.
- Response:
{ "success": true, "message": "Group settings updated", "data": { "groupId": "group_0fe71c5d810c4b2aa03b65c17b96f65c", "settings": { "onlyAdminsCanSend": false, "onlyAdminsCanAddMembers": true } } }settings: The updated group settings.
- Endpoint:
-
4.6 Change a Member's Role
- Endpoint:
POST /api/groups/members/role - Description: Changes a member's role within the group (e.g., from "member" to "admin").
- Request Body (JSON):
{ "userId": "67f640afb2dffb1086532c3f", "groupId": "group_51677004832949ef93a90977d103c862", "memberId": "67f640e6b2dffb1086532c42", "newRole": "admin" }userId: The ID of the user initiating the role change (must have permission).groupId: The ID of the group.memberId: The ID of the member whose role is being changed.newRole: The new role for the member (e.g., "admin", "member").
- Response:
{ "success": true, "message": "Member role updated", "data": { "groupId": "group_0fe71c5d810c4b2aa03b65c17b96f65c", "memberId": "67f640e6b2dffb1086532c42", "newRole": "admin" } } * `newRole`: The updated role.
- Endpoint:
-
4.7 Get User's Groups
- Endpoint:
GET /api/groups/user/:userId - Description: Retrieves a list of groups that a user belongs to.
- Request:
GET /api/groups/user/67f640afb2dffb1086532c3fuserId: The ID of the user.
- Response:
{ "success": true, "data": [ { "groupId": "group_0fe71c5d810c4b2aa03b65c17b96f65c", "name": "DishIs Technologies", "description": "Group for DIT members", "createdAt": "2025-04-10T16:38:09.738Z" }, { "groupId": "group_3bce106b4d934c20aa129278f29af2e9", "name": "DishIs Technologies", "description": "Group for DIT members", "createdAt": "2025-04-09T18:06:40.295Z" } ] } * The `data` array contains an array of group objects, with basic group information.
- Endpoint:
-
4.8 Delete a Group
- Endpoint:
POST /api/groups/delete - Description: Deletes an existing group.
- Request Body (JSON):
{ "userId": "67f640afb2dffb1086532c3f", "groupId": "group_51677004832949ef93a90977d103c862" }userId: The ID of the user initiating the deletion (must be the group admin or have sufficient privileges).groupId: The ID of the group to delete.
- Response:
{ "success": true, "message": "Group deleted successfully", "data": { "groupId": "group_3bce106b4d934c20aa129278f29af2e9" } } * `groupId`: The ID of the deleted group.
- Endpoint:
5. Group Messaging
-
5.1 Send a Message to a Group
- Endpoint:
POST /api/group-messages/send - Description: Sends a message to all members of a group.
- Request Body (JSON):
{ "senderId": "67f640afb2dffb1086532c3f", "groupId": "group_0fe71c5d810c4b2aa03b65c17b96f65c", "encryptedContent": "{\"message\":\"wm0dZJ+UlG1KB0AEwvKVd1cQiVwnRabWUH2/QaC86x8=\",\"keys\":[\"cc+rpjCg++FSWPToUk7qZRQZ9mhP6SlEIfSiesStKd0skKqTe12I2byoTnkAH8AbdZk41B/2fXd0m+eb+mtfNWZ11Rm1OrMGxd/IbHxMcE7ch3YuWsedInpnAvPavPUFCF/1i4m/oj10Id/m09gvObGCwXW+gQluhqJrCKTraTsYhYbNCArvnVl62oN7LW9E7ss68obp+6yVAzQrrlZYBipK6UsvwSFvnfZE8V+TY7UElJGcFgPMYKngEg6RvygWzZFMD9mj5He8Jea4jYx4/kcD1tJfOov14ToppEAB7doEzoKrggnQGB180dbmLBK4jKoeVuuTFiWdltY6FOIUcA==\"],\"iv\":\"uTiFPIa04CDXI4gM3sEAVA==\"}", "type": "text", "mediaId": "", "replyToId": "" }senderId: The ID of the user sending the message.groupId: The ID of the group.encryptedContent: The encrypted message content. Important: In group messaging, the encryption likely works differently.message: The encrypted payload.keys: An array of encrypted AES keys. Each key is encrypted with the public key of a different member of the group. This ensures that only the intended recipients can decrypt the message. If it is not array, it is most likey encrypted with group level key.iv: The initialization vector.
type: The message type.mediaId: The ID of the media file (if any).replyToId: The ID of the message being replied to (if any).
- Response:
{ "success": true, "data": { "messageId": "msg_47b3bb163b9b49288fed905a10461c59", "groupId": "group_0fe71c5d810c4b2aa03b65c17b96f65c", "sentAt": "2025-04-13T05:59:45.530Z" } }messageId: The ID of the message.groupId: The ID of the group.sentAt: The timestamp.
- Socket.io Event: The server emits a
new_group_messageevent to each member of the group.for (const memberId of memberIds) { io.to(memberId).emit("new_group_message", { messageId, groupId, senderId, type, mediaId, replyToId, sentAt: message.sentAt, }); }
- Each member receives the metadata, allowing their client to fetch and decrypt the message.
- Endpoint:
-
5.2 Get Group Messages
- Endpoint:
GET /api/group-messages/:groupId - Description: Retrieves messages from a group. Supports pagination.
- Request:
GET /api/group-messages/group_51677004832949ef93a90977d103c862?userId=67f640afb2dffb1086532c3f&limit=10&before=1744209600000groupId: The ID of the group.- Query Parameters:
userId: The ID of the user requesting the messages (used for permissions/filtering).limit: The maximum number of messages to retrieve (default: 10).before: A timestamp (in milliseconds) representing the point before which to retrieve messages. Used for pagination.
- Response:
{ "success": true, "data": [ { "messageId": "msg_2ddc7598a3894b8f80b53385718e4f37", "groupId": "group_0fe71c5d810c4b2aa03b65c17b96f65c", "senderId": "67f640afb2dffb1086532c3f", "content": "{\"message\":\"o6lmBlc449ZoDCxqdHB1ZvMC2DgI8rSVGXpOSpe4sp887fwo+yT676pfIGB37Xof\",\"iv\":\"3OTOxcz9aup5nIAeqXPmqQ==\",\"encryptedKeys\":{\"67f640e6b2dffb1086532c42\":\"emhaO9vuRxpuWz5NXebahWOhq21EPcOOj4AupnFwEqgD5LWBP86fMup/Yaqo1HrkCKX+fQEVIIlQjFInNbtafnbAu2ng7PD6PkHN7qqF3kXihhrfF/wpZL743Dn/05W1II+rNu6V3ORo6B6EL6pNxn1qC5SnirB19ezyRcO9oyIMBfKTviPXqEcRDfY9tq7nSW3xWFehJ2cQP6Bf7sIBpM8cWRywGoZ35Ke2GeZdZIeCSSEogRXGc0iBg1ZL4pVNhTWd8VGLg/qoTdFzbS7BQcQkUEcVKZnYTMWZCTXqPjzR7QY0XwHKwaa5yGyke08Al5GRKCQn+95m3C+AHgRhbA==\",\"67f640afb2dffb1086532c3f\":\"A5jlKFuBl6oNMo3r57WVFWTJCY6CwefwsChdGMeeVocyqlBv+AVjZ34sX+21Z8biyDGMMTBw8rKokqwBwqU2HTjDLIpOQ09wapOh+1UE75wAGUHBsynEEz90ANQlKLAdaedxSmTInV/YdyJdlDNaxv6wfL+5Kl3EjdPNs/oraBVoArAx0XzJhnoF+TVkDe3iPe8Y8wxHAiH6WA+z9Dwodhh3OwDxANRjKzDT4Zo/PeizR2f/IiH16R/YxeyCBFHbnunGDVZTJzQaBDLK8pBikbepQEXa/6+yKIVdPXwYKEdGQGjQhaSNH0A26vGH8iZG7g6uW2apoMocB+WrXWxqCQ==\"}}", "contentHash": "0531df067680dc4766c4cf6fdcdfe5d51ec637bd2829ba04085088a1a852c1c5", "type": "text", "mediaId": "", "replyToId": "", "sentAt": "2025-04-11T08:33:49.437Z" } ] }- The
dataarray contains an array of message objects. content: Contains the encrypted content,iv, and theencryptedKeysobject where each user id is mapped with AES key encrypted with that user public key.
- The
- Endpoint:
-
5.3 React to a Group Message
- Endpoint:
POST /api/group-messages/react - Description: Adds a reaction to a group message.
- Request Body (JSON):
{ "userId": "value", "messageId": "value", "reaction": "😃" }userId: The ID of the user reacting.messageId: The ID of the message being reacted to.reaction: The reaction (e.g., an emoji).
- Response:
{ "success": true, "data": { "messageId": "msg_2ddc7598a3894b8f80b53385718e4f37", "groupId": "group_0fe71c5d810c4b2aa03b65c17b96f65c", "reaction": "😃" } } - Socket.io Event: The server emits a
group_message_reactionevent to all group members.const memberIds = group.members.map((m) => m.userId.toString()) for (const memberId of memberIds) { io.to(memberId).emit("group_message_reaction", { messageId, groupId: message.groupId, userId, reaction, }) }
messageId: The ID of the message.groupId: The ID of the group.userId: The ID of the user who reacted.reaction: The reaction.
- Endpoint:
-
5.4 Delete a Group Message
- Endpoint:
POST /api/group-messages/delete - Description: Deletes a message in a group.
- Request Body (JSON):
{ "userId": "67f640afb2dffb1086532c3f", "messageId": "msg_51677004832949ef93a90977d103c862", "deleteForEveryone": false }userId: The ID of the user initiating the deletion.messageId: The ID of the message to delete.deleteForEveryone: Whether to delete for everyone or just the user.
- Response:
{ "success": true, "message": "Message deleted successfully", "data": { "messageId": "msg_2ddc7598a3894b8f80b53385718e4f37", "groupId": "group_0fe71c5d810c4b2aa03b65c17b96f65c", "deleteForEveryone": false } } - Socket.io Event: The server emits a
group_message_deletedevent to all group members ifdeleteForEveryoneis true.const memberIds = group.members.map((m) => m.userId.toString()) for (const memberId of memberIds) { io.to(memberId).emit("group_message_deleted", { messageId, groupId: message.groupId, deleteForEveryone: true, }) }
- Endpoint:
-
5.5 Update Group Message Status
- Endpoint:
POST /api/group-messages/status - Description: Updates the status of a group message (e.g., "delivered", "seen").
- Request Body (JSON):
{ "userId": "67f640afb2dffb1086532c3f", "messageId": "msg_51677004832949ef93a90977d103c862", "status": "delivered" }userId: The ID of the user updating the status.messageId: The ID of the message.status: The new status.
- Response:
{ "success": true, "data": { "messageId": "msg_725d2648b72e4df38c484da16ac1fb9f", "groupId": "group_0fe71c5d810c4b2aa03b65c17b96f65c", "status": "delivered", "updatedAt": "2025-04-11T08:44:36.917Z" } } - Socket.io Event: The server emits a
group_message_status_updateevent to the sender of the message.io.to(message.senderId.toString()).emit("group_message_status_update", { messageId, groupId: message.groupId, userId, status, timestamp: new Date(), })
- Endpoint:
6. Communities
-
6.1 Create a New Community
- Endpoint:
POST /api/communities/create - Description: Creates a new community.
- Request Body (JSON):
{ "userId": "67f640afb2dffb1086532c3f", "name": "DishIs Technologies", "description": "Where technologies happens", "isPrivate": true, "encryptedAESKey": "tyry", "plaintextAESKey": "", "avatar": "https://github.com/dishis.png", "coverImage": "" }userId: The ID of the user creating the community.name: The name of the community.description: A description of the community.isPrivate: A boolean indicating whether the community is private (invite-only) or public.encryptedAESKey: If the community is private (and E2EE), this is the community's AES key, encrypted with the server's public key or some other secure mechanism for storage. If the community is public (isPrivate: false) AND thee2eeModewill be"trusted", this key contains the AES key encrypted by the server and distributed to all users.plaintextAESKey: Only applicable whenisPrivateisfalseand E2EE is not enabled (or is server-trusted). Leave empty for private communities with full E2EE.avatar: URL for the community's avatar.coverImage: URL for the community's cover image.
- Response:
{ "success": true, "data": { "communityId": "comm_0ea7709d84de426789ad51184c4a2f23", "name": "DishIs Technologies", "description": "Where technologies happens", "createdBy": "67f640afb2dffb1086532c3f", "defaultChannel": "chan_2855a2a966ee485c8c5d96746da0f309", "isPrivate": true, "e2eeMode": "true", "createdAt": "2025-04-13T07:04:43.358Z" } } * `communityId`: The ID of the new community. Store this! * `defaultChannel`: The ID of the default channel created for the community. * `e2eeMode`: `"true"` indicates full E2EE is enabled. `"trusted"` indicates server trusted e2ee, meaning server has access to plaintext messages. This is typically used for public communitites.
- Endpoint:
-
6.2 Get Community Details
- Endpoint:
GET /api/communities/:communityId - Description: Retrieves details of a community.
- Request:
GET /api/communities/comm_id-here?userId=67f640afb2dffb1086532c3fcommunityId: The ID of the community.- Query Parameter:
userId: The ID of the user requesting the details.
- Response:
{ "success": true, "data": { "communityId": "comm_0ea7709d84de426789ad51184c4a2f23", "name": "DishIs Technologies", "description": "Where technologies happens", "createdBy": "67f640afb2dffb1086532c3f", "isPrivate": true, "channelIds": [ "chan_2855a2a966ee485c8c5d96746da0f309" ], "createdAt": "2025-04-13T07:04:43.367Z", "e2eeMode": "true"(or "trusted" which means server- trusted or public community) } } * `channelIds`: An array of channel IDs associated with the community. * `e2eeMode`: "true" or "trusted".
- Endpoint:
-
6.3 Join a Community
- Endpoint:
POST /api/communities/join - Description: Allows a user to join a community.
- Request Body (JSON):
{ "userId": "67f640afb2dffb1086532c3f", "communityId": "comm_id-here" }userId: The ID of the user joining.communityId: The ID of the community.
- Response (Public Community):
{ "success": true, "message": "Successfully joined the community", "data": { "communityId": "comm_2fffd73be3ce47d1a7f558a6e6d61df2", "userId": "67f8d7cc8276b11998f0f3d0", "role": "member", "joinedAt": "2025-04-11T08:51:36.100Z" } } * `role`: The user's role in the community (e.g., "member"). - Response (Private Community):
{ "success": true, "message": "Join request submitted. Awaiting admin approval.", "data": { "communityId": "comm_0ea7709d84de426789ad51184c4a2f23", "userId": "67f640e6b2dffb1086532c42", "status": "pending" } } * `status`: "pending" indicates that the user's request needs to be approved by a community admin.
- Endpoint:
-
6.4 Leave a Community
- Endpoint:
POST /api/communities/leave - Description: Allows a user to leave a community.
- Request Body (JSON):
{ "userId": "67f8d7cc8276b11998f0f3d0", "communityId": "comm_2fffd73be3ce47d1a7f558a6e6d61df2" }userId: The ID of the user leaving.communityId: The ID of the community.
- Response:
{ "success": true, "message": "Successfully left the community", "data": { "communityId": "comm_2fffd73be3ce47d1a7f558a6e6d61df2", "userId": "67f8d7cc8276b11998f0f3d0" } }
- Endpoint:
-
6.5 Create a Channel
- Request Body (JSON):
{ "userId": "67f640afb2dffb1086532c3f", "communityId": "comm_id-here", "name": "DIT Maildrop", "description": "A text channel for Maildrop API by DishIs Technologies", "type": "text", "isPrivate": true, "allowedMembers": [ "67f640e6b2dffb1086532c42" ], "encryptedKeysFromClient": { "67f640e6b2dffb1086532c42": "hhhgfhgfh" } }userId: The ID of the user creating the channel (must have permission).communityId: The ID of the community.name: The name of the channel.description: A description of the channel.type: The channel type (e.g., "text", "voice").isPrivate: A boolean indicating whether the channel is private (only accessible to specific members) or public (accessible to all community members).allowedMembers: An array of user IDs that are allowed to access the channel (only applicable ifisPrivateis true).encryptedKeysFromClient: CRITICAL for E2EE: A dictionary where each key is auserIdfrom theallowedMembersarray, and the value is the channel's AES key, encrypted with the public key of that user. This ensures that only the allowed members can decrypt messages in the channel. If the community istrusted, then this will be encrypted with server's public key to manage enc keys.
- Response:
{ "success": true, "data": { "channelId": "chan_a0b518499c7e482697f567e706a5f502", "communityId": "comm_2fffd73be3ce47d1a7f558a6e6d61df2", "name": "DIT Maildrop", "description": "A text channel for Maildrop API by DishIs Technologies", "type": "text", "isPrivate": true, "createdAt": "2025-04-11T08:53:02.252Z" } }channelId: The ID of the new channel. Store this!
- Request Body (JSON):
-
6.6 Get Community Channels
- Endpoint:
GET /api/communities/:communityId/channels - Description: Retrieves a list of channels within a community.
- Request:
GET /api/communities/comm_2fffd73be3ce47d1a7f558a6e6d61df2/channels?userId=67f640e6b2dffb1086532c42communityId: The ID of the community.- Query Parameter (Optional):
userId: The ID of the user requesting the channels. Used for permission checking (e.g., to only show channels the user has access to).
- Response:
{ "success": true, "data": [ { "channelId": "chan_7e0822f06a244cb49182de9aa120e949", "communityId": "comm_2fffd73be3ce47d1a7f558a6e6d61df2", "name": "general", "description": "General discussion channel", "type": "text", "isPrivate": false, "createdAt": "2025-04-11T08:48:16.056Z", "updatedAt": "2025-04-11T08:48:16.056Z" }, { "channelId": "chan_a0b518499c7e482697f567e706a5f502", "communityId": "comm_2fffd73be3ce47d1a7f558a6e6d61df2", "name": "DIT Maildrop", "description": "A text channel for Maildrop API by DishIs Technologies", "type": "text", "isPrivate": true, "createdAt": "2025-04-11T08:53:02.252Z", "updatedAt": "2025-04-11T08:53:02.252Z" } ] }- The
dataarray contains an array of channel objects.
- The
- Endpoint:
-
6.7 Get User's Communities
- Endpoint:
GET /api/communities/user/:userId - Description: Retrieves a list of communities that a user belongs to.
- Request:
GET /api/communities/user/67f640afb2dffb1086532c3fuserId: The ID of the user.
- Response:
{ "success": true, "data": [ { "communityId": "comm_2fffd73be3ce47d1a7f558a6e6d61df2", "name": "DishIs Technologies", "description": "Where technologies happens", "isPrivate": false, "createdAt": "2025-04-11T08:48:16.060Z" }, { "communityId": "comm_08fd4359a0f44fdcb982539fae3faab9", "name": "DishIs Technologies", "description": "Where technologies happens", "isPrivate": true, "createdAt": "2025-04-11T08:45:12.696Z" }, { "communityId": "comm_f2b70800c38041eab88ba29e43617c47", "name": "DishIs Technologies", "description": "Where technologies happens", "isPrivate": true, "createdAt": "2025-04-09T18:50:50.439Z" } ] }- The
dataarray contains an array of community objects.
- The
- Endpoint:
7. Channel Messaging
-
7.1 Send a Message to a Channel
- Endpoint:
POST /api/channel-messages/send - Description: Sends a message to a channel within a community.
- Request Body (JSON):
{ "senderId": "67f640afb2dffb1086532c3f", "channelId": "chan_2855a2a966ee485c8c5d96746da0f309", "content": "{\"message\":\"wm0dZJ+UlG1KB0AEwvKVd1cQiVwnRabWUH2/QaC86x8=\",\"key\":\"cc+rpjCg++FSWPToUk7qZRQZ9mhP6SlEIfSiesStKd0skKqTe12I2byoTnkAH8AbdZk41B/2fXd0m+eb+mtfNWZ11Rm1OrMGxd/IbHxMcE7ch3YuWsedInpnAvPavPUFCF/1i4m/oj10Id/m09gvObGCwXW+gQluhqJrCKTraTsYhYbNCArvnVl62oN7LW9E7ss68obp+6yVAzQrrlZYBipK6UsvwSFvnfZE8V+TY7UElJGcFgPMYKngEg6RvygWzZFMD9mj5He8Jea4jYx4/kcD1tJfOov14ToppEAB7doEzoKrggnQGB180dbmLBK4jKoeVuuTFiWdltY6FOIUcA==\",\"iv\":\"uTiFPIa04CDXI4gM3sEAVA==\"}", "type": "text", "mediaId": "", "replyToId": "" }senderId: The ID of the user sending the message.channelId: The ID of the channel.content: The encrypted message content.- If the channel is private (E2EE), the
keywould be the AES key of the channel that is encrypted for each member in theencryptedKeysFromClientendpoint from6.5 Create a channel. This decryption key should be distributed while creating a private channel - If the channel is public, the key will be sent by server to authorized members.
messageis encrypted payload to sendivis initialization vector
- If the channel is private (E2EE), the
type: The message type.mediaId: The ID of the media file (if any).replyToId: The ID of the message being replied to (if any).
- Response:
{ "success": true, "data": { "messageId": "msg_5cce77b169df44a3a55b1e76b7332aae", "channelId": "chan_2855a2a966ee485c8c5d96746da0f309", "sentAt": "2025-04-13T16:56:03.789Z" } } - Socket.io Event: The server emits a
new_channel_messageevent to each member who has access to the channel.for (const memberId of memberIds) { io.to(memberId).emit("new_channel_message", { messageId, channelId, communityId: channel.communityId, senderId, type, mediaId, replyToId, sentAt: message.sentAt, }); }
- Endpoint:
-
7.2 Get Channel Messages
- Endpoint:
GET /api/channel-messages/:channelId - Description: Retrieves messages from a channel. Supports pagination.
- Request:
GET /api/channel-messages/chan_2855a2a966ee485c8c5d96746da0f309?userId=67f640afb2dffb1086532c3f&limit=10&before=1channelId: The ID of the channel.- Query Parameters:
userId: The ID of the user requesting the messages (used for permissions/filtering).limit: The maximum number of messages to retrieve (default: 10).before: A timestamp representing the point before which to retrieve messages. Used for pagination.
- Response:
{ "success": true, "data": [ { "messageId": "msg_5cce77b169df44a3a55b1e76b7332aae", "channelId": "chan_2855a2a966ee485c8c5d96746da0f309", "senderId": "67f640afb2dffb1086532c3f", "content": "{\"message\":\"wm0dZJ+UlG1KB0AEwvKVd1cQiVwnRabWUH2/QaC86x8=\",\"key\":\"cc+rpjCg++FSWPToUk7qZRQZ9mhP6SlEIfSiesStKd0skKqTe12I2byoTnkAH8AbdZk41B/2fXd0m+eb+mtfNWZ11Rm1OrMGxd/IbHxMcE7ch3YuWsedInpnAvPavPUFCF/1i4m/oj10Id/m09gvObGCwXW+gQluhqJrCKTraTsYhYbNCArvnVl62oN7LW9E7ss68obp+6yVAzQrrlZYBipK6UsvwSFvnfZE8V+TY7UElJGcFgPMYKngEg6RvygWzZFMD9mj5He8Jea4jYx4/kcD1tJfOov14ToppEAB7doEzoKrggnQGB180dbmLBK4jKoeVuuTFiWdltY6FOIUcA==\",\"iv\":\"uTiFPIa04CDXI4gM3sEAVA==\"}", "contentHash": "a8ccbf542370d49f9bfa6cfe85889a0f801bcc2604ced06ebb8f8c7e07374ab2", "type": "text", "mediaId": "", "replyToId": "", "sentAt": "2025-04-13T16:56:03.789Z" } ] }
- Endpoint:
-
7.3 Pin a Channel Message
- Endpoint:
POST /api/channel-messages/pin - Description: Pins a message to the channel, making it easily accessible.
- Request Body (JSON):
{ "userId": "67f640afb2dffb1086532c3f", "messageId": "msg_5cce77b169df44a3a55b1e76b7332aae" }userId: The ID of the user pinning the message (must have permission).messageId: The ID of the message to pin.
- Response:
{ "success": true, "data": { "messageId": "msg_5cce77b169df44a3a55b1e76b7332aae", "channelId": "chan_2855a2a966ee485c8c5d96746da0f309", "isPinned": true } }isPinned: A boolean indicating that the message is now pinned.
- Socket.io Event: The server emits a
channel_message_pinnedevent to all members with access to the channel.for (const memberId of memberIds) { io.to(memberId).emit("channel_message_pinned", { messageId, channelId: message.channelId, communityId: channel.communityId, pinnedBy: userId, pinnedAt: new Date(), }) }
- Endpoint:
-
7.4 Get Pinned Messages
- Endpoint:
GET /api/channel-messages/:channelId/pinned - Description: Retrieves the pinned messages from a channel.
- Request:
GET /api/channel-messages/chan_2855a2a966ee485c8c5d96746da0f309/pinned?userId=67f640afb2dffb1086532c3fchannelId: The ID of the channel.- Query Parameter:
userId: User ID for permission check
- Response:
{ "success": true, "data": [ { "messageId": "msg_5cce77b169df44a3a55b1e76b7332aae", "channelId": "chan_2855a2a966ee485c8c5d96746da0f309", "senderId": "67f640afb2dffb1086532c3f", "content": "{\"message\":\"wm0dZJ+UlG1KB0AEwvKVd1cQiVwnRabWUH2/QaC86x8=\",\"key\":\"cc+rpjCg++FSWPToUk7qZRQZ9mhP6SlEIfSiesStKd0skKqTe12I2byoTnkAH8AbdZk41B/2fXd0m+eb+mtfNWZ11Rm1OrMGxd/IbHxMcE7ch3YuWsedInpnAvPavPUFCF/1i4m/oj10Id/m09gvObGCwXW+gQluhqJrCKTraTsYhYbNCArvnVl62oN7LW9E7ss68obp+6yVAzQrrlZYBipK6UsvwSFvnfZE8V+TY7UElJGcFgPMYKngEg6RvygWzZFMD9mj5He8Jea4jYx4kcD1tJfOov14ToppEAB7doEzoKrggnQGB180dbmLBK4jKoeVuuTFiWdltY6FOIUcA==\",\"iv\":\"uTiFPIa04CDXI4gM3sEAVA==\"}", "contentHash": "a8ccbf542370d49f9bfa6cfe85889a0f801bcc2604ced06ebb8f8c7e07374ab2", "type": "text", "mediaId": "", "replyToId": "", "sentAt": "2025-04-13T16:56:03.789Z", "isPinned": true } ] }
- Endpoint:
8. Status Updates
-
8.1 Create a Status Update
- Endpoint:
POST /api/statuses/create - Description: Creates a new status update for the user.
- Request Body (JSON):
{ "userId": "67f640afb2dffb1086532c3f", "type": "text", "content": "{\"message\":\"wm0dZJ+UlG1KB0AEwvKVd1cQiVwnRabWUH2/QaC86x8=\",\"key\":\"cc+rpjCg++FSWPToUk7qZRQZ9mhP6SlEIfSiesStKd0skKqTe12I2byoTnkAH8AbdZk41B/2fXd0m+eb+mtfNWZ11Rm1OrMGxd/IbHxMcE7ch3YuWsedInpnAvPavPUFCF/1i4m/oj10Id/m09gvObGCwXW+gQluhqJrCKTraTsYhYbNCArvnVl62oN7LW9E7ss68obp+6yVAzQrrlZYBipK6UsvwSFvnfZE8V+TY7UElJGcFgPMYKngEg6RvygWzZFMD9mj5He8Jea4jYx4kcD1tJfOov14ToppEAB7doEzoKrggnQGB180dbmLBK4jKoeVuuTFiWdltY6FOIUcA==\",\"iv\":\"uTiFPIa04CDXI4gM3sEAVA==\"}", "mediaId": "id", "backgroundColor": "black", "visibleTo": "specific", "specificUsers": [ "67f640e6b2dffb1086532c42", "67f640afb2dffb1086532c3f" ], "expiresAt": 24, "encryptedKeys": { "67f640e6b2dffb1086532c42": "newfsdfsdf", "67f640afb2dffb1086532c3f": "sdfasdfasdf" } }userId: The ID of the user creating the status.type: The type of status (e.g., "text", "image", "video").content: The encrypted content of the status update.message: encrypted messagekey: Encrypted key for each user mentionediv: Initialization vector
mediaId: The ID of the media file (if any).backgroundColor: The background color for the status display.visibleTo: Indicates who can view the status update. Possible values:"all": Visible to all contacts."specific": Visible only to specific users.
specificUsers: An array of user IDs to which the status is visible (only applicable ifvisibleTois"specific").expiresAt: The number of hours after which the status update will expire (e.g., 24 for 24 hours).encryptedKeys: key for each visible users
- Response:
{ "success": true, "data": { "statusId": "status_4af4a683559a4f1ab03f618242c2b9f2", "type": "text", "createdAt": "2025-04-15T17:40:36.632Z", "expiresAt": "2025-04-16T17:40:36.632Z" } }statusId: The ID of the new status update.
- Endpoint:
-
8.2 Get User's Statuses
- Endpoint:
GET /api/statuses/user/:userId - Description: Retrieves a list of status updates for a given user.
- Request:
GET /api/statuses/user/67f640afb2dffb1086532c3f?viewerId=67f640e6b2dffb1086532c42userId: The ID of the user whose statuses are being retrieved.- Query Parameter (Optional):
viewerId: The ID of the user viewing the statuses. This is used for permission checking (to ensure the viewer is authorized to see the statuses).
- Response:
{ "success": true, "data": [ { "statusId": "status_aa2423b64dc143258bc0e24c61f20ea9", "userId": "67f640afb2dffb1086532c3f", "type": "text", "content": "{\"message\":\"wm0dZJ+UlG1KB0AEwvKVd1cQiVwnRabWUH2/QaC86x8=\",\"key\":\"cc+rpjCg++FSWPToUk7qZRQZ9mhP6SlEIfSiesStKd0skKqTe12I2byoTnkAH8AbdZk41B/2fXd0m+eb+mtfNWZ11Rm1OrMGxd/IbHxMcE7ch3YuWsedInpnAvPavPUFCF/1i4m/oj10Id/m09gvObGCwXW+gQluhqJrCKTraTsYhYbNCArvnVl62oN7LW9E7ss68obp+6yVAzQrrlZYBipK6UsvwSFvnfZE8V+TY7UElJGcFgPMYKngEg6RvygWzZFMD9mj5He8Jea4jYx4kcD1tJfOov14ToppEAB7doEzoKrggnQGB180dbmLBK4jKoeVuuTFiWdltY6FOIUcA==\",\"iv\":\"uTiFPIa04CDXI4gM3sEAVA==\"}", "encryptedKey": "newfsdfsdf", "createdAt": "2025-04-15T17:44:46.892Z", "expiresAt": "2025-04-16T17:44:46.892Z" } ] }- Each status object includes the
encryptedKeyneeded to decrypt the content if the status update is E2EE.
- Each status object includes the
- Endpoint:
-
8.3 Get Status Details
- Endpoint:
GET /api/statuses/:statusId - Description: Retrieves the details of a specific status update.
- Request:
GET /api/statuses/status_aa2423b64dc143258bc0e24c61f20ea9?viewerId=67f640e6b2dffb1086532c42statusId: The ID of the status update.- Query Parameter:
viewerId: The ID of the user viewing the status (used for permission checking).
- Response:
{ "success": true, "data": { "statusId": "status_aa2423b64dc143258bc0e24c61f20ea9", "userId": "67f640afb2dffb1086532c3f", "type": "text", "content": "{\"message\":\"wm0dZJ+UlG1KB0AEwvKVd1cQiVwnRabWUH2/QaC86x8=\",\"key\":\"cc+rpjCg++FSWPToUk7qZRQZ9mhP6SlEIfSiesStKd0skKqTe12I2byoTnkAH8AbdZk41B/2fXd0m+eb+mtfNWZ11Rm1OrMGxd/IbHxMcE7ch3YuWsedInpnAvPavPUFCF/1i4m/oj10Id/m09gvObGCwXW+gQluhqJrCKTraTsYhYbNCArvnVl62oN7LW9E7ss68obp+6yVAzQrrlZYBipK6UsvwSFvnfZE8V+TY7UElJGcFgPMYKngEg6RvygWzZFMD9mj5He8Jea4jYx4kcD1tJfOov14ToppEAB7doEzoKrggnQGB180dbmLBK4jKoeVuuTFiWdltY6FOIUcA==\",\"iv\":\"uTiFPIa04CDXI4gM3sEAVA==\"}", "mediaId": "id", "backgroundColor": "black", "fontStyle": "default", "visibleTo": "specific", "specificUsers": [ "67f640e6b2dffb1086532c42", "67f640afb2dffb1086532c3f" ], "excludedUsers": [], "encryptedKeys": { "67f640e6b2dffb1086532c42": "newfsdfsdf", "67f640afb2dffb1086532c3f": "sdfasdfasdf" }, "createdAt": "2025-04-15T17:44:46.892Z", "expiresAt": "2025-04-16T17:44:46.892Z" } }content,mediaId,backgroundColor,fontStyle,visibleTo,specificUsers,excludedUsers
- Endpoint:
-
8.4 Delete a Status
- Endpoint:
POST /api/statuses/delete - Description: Deletes an existing status update.
- Request Body (JSON):
{ "userId": "67f640afb2dffb1086532c3f", "statusId": "status_aa2423b64dc143258bc0e24c61f20ea9" }userId: The ID of the user deleting the status (must be the owner).statusId: The ID of the status update to delete.
- Response:
{ "success": true, "message": "Status deleted successfully", "data": { "statusId": "status_aa2423b64dc143258bc0e24c61f20ea9" } }
- Endpoint:
-
8.5 Get Status Viewers
- Endpoint:
GET /api/statuses/:statusId/viewers - Description: Retrieves a list of users who have viewed a specific status update.
- Request:
GET /api/statuses/status_aa2423b64dc143258bc0e24c61f20ea9/viewers?userId=67f640afb2dffb1086532c3fstatusId: The ID of the status update.- Query Parameter:
userId: User ID of the status creater for checking
- Response:
{ "success": true, "data": { "statusId": "status_aa2423b64dc143258bc0e24c61f20ea9", "viewCount": 1, "viewers": [ { "userId": "67f640e6b2dffb1086532c42", "username": "Ishant", "viewedAt": "2025-04-15T17:44:57.820Z" } ] } }viewCount: The number of viewers.viewers: An array of viewer objects, including their user ID, username, and the timestamp when they viewed the status.
- Endpoint:
9. Media
-
9.1 Upload Media File
- Request:
- Form Data Fields:
encryptedMetadata: A JSON string containing metadata about the encrypted file:{ "fileType": "image", "originalName": "cat.png", "size": 12000000, "mimeType": "image/png", "iv": "fileIv", "thumbnailIv": "thumbIv", "encryptedKey": "encryptedAESKey" }fileType: The file type (e.g., "image", "video", "audio").originalName: The original filename of the file.size: The file size in bytes.mimeType: The MIME type of the file (e.g., "image/png", "video/mp4").iv: The initialization vector (IV) used to encrypt the file.thumbnailIv: The IV used to encrypt the thumbnail (if a thumbnail is uploaded).encryptedKey: The AES encryption key that was used for the original file encryption. This is AES Key encrypted using the recipient user public key for E2EE or group level enc key.
thumbnail(Optional): An encrypted thumbnail of the media file. Should be encrypted in the same manner as the main file.hasThumbnail: A boolean indicating whether a thumbnail file was uploaded.
- Form Data Fields:
- Response:
{ "success": true, "data": { "fileId": "file_af789791d82e4634a7231a9ed4a101fe", "fileType": "image", "mimeType": "image/png", "uploadedAt": "2025-04-15T17:16:26.809Z" } }fileId: The unique ID of the uploaded file. Store this!fileType: The file type.mimeType: The MIME type.uploadedAt: The timestamp when the file was uploaded.
- Request:
-
9.2 Get Media File
- Endpoint:
GET /api/media/:fileId - Description: Retrieves a media file.
- Request:
GET /api/media/file_af789791d82e4634a7231a9ed4a101fe?thumbnail=truefileId: The ID of the file.- Query Parameter:
thumbnail: A boolean indicating whether to retrieve the thumbnail (if available) instead of the original file.
- Response:
{ "success": true, "data": { "fileId": "file_af789791d82e4634a7231a9ed4a101fe", "fileType": "image", "mimeType": "image/png", "size": 12000000, "originalName": "cat.png", "thumbnailPath": "/root/message-api/uploads/5600e3e2-cc56-4474-903e-ef5bc0ca26c0.asc", "filePath": "/root/message-api/uploads/b8f915f2-83bd-41a1-8f81-524bbfe33e85.asc", "fileIv": "fileIv", "thumbIv": "thumbIv", "encryptedAESKey": "encryptedAESKey", "userId": "67f640afb2dffb1086532c3f", "uploadedAt": "2025-04-15T17:16:26.809Z", "expiresAt": null }, "file": "/root/message-api/uploads/5600e3e2-cc56-4474-903e-ef5bc0ca26c0.asc" }filePath: The server-side path to the encrypted file.thumbnailPath: The server-side path to the encrypted thumbnail.fileIv: The initialization vector used to encrypt the file (needed for decryption).thumbIv: The initialization vector used to encrypt the thumbnail.encryptedAESKey:The AES encryption key that was used for the original file encryption(needed for decryption). This key is AES encrypted using recipient's user public key for E2EE or group level enc keyuserId: The ID of the user who uploaded the file.expiresAt: Time for expirationfile: The actual path to the file on the server. The content of the response is the encrypted file data, which needs to be decrypted using theencryptedAESKeyandfileIv. Ifthumbnail=true, thefilefield contains the encrypted thumbnail data.
- Endpoint:
10. Analytics
-
10.1 Get User Statistics
- Endpoint:
GET /api/analytics/user/:userId - Description: Retrieves statistics for a specific user.
- Request:
GET /api/analytics/user/67f640afb2dffb1086532c3fuserId: The ID of the user.
- Response:
{ "success": true, "data": { "messagesSent": 14, "messagesReceived": 0, "totalMessages": 14, "activeChatsCount": 0, "lastActiveAt": null } }messagesSent: The number of messages sent by the user.messagesReceived: The number of messages received by the user.totalMessages: The total number of messages (sent + received).activeChatsCount: The number of active chats the user is involved in.lastActiveAt: The timestamp when the user was last active.
- Endpoint:
-
10.2 Get Active Chats
- Endpoint:
GET /api/analytics/active-chats/:userId - Description: Retrieves a list of active chats for a specific user.
- Request:
GET /api/analytics/active-chats/67f640afb2dffb1086532c3f?limit=10userId: The ID of the user.- Query Parameter:
limit: Limit for the number of chats to return
- Response:
{ "success": true, "data": [ { "userId": "67f640e6b2dffb1086532c42", "lastMessageAt": "2025-04-12T16:01:29.161Z", "lastMessageId": "msg_1a1294deaad24b168b56f192064c8229" } ] }userId: The ID of the other user in the chat.lastMessageAt: The timestamp of the last message exchanged in the chat.lastMessageId: The ID of the last message exchanged in the chat.
- Endpoint:
-
10.3 Get Message Count
- Endpoint:
GET /api/analytics/message-count/:userId - Description: Retrieves the message count for a user within a specified period.
- Request:
GET /api/analytics/message-count/67f640afb2dffb1086532c3f?period=monthuserId: The ID of the user.- Query Parameter:
period: The time period for which to retrieve the message count. Possible values:"month".
- Response:
{ "success": true, "data": { "count": 14, "period": "month" } }count: The message count for the specified period.period: The time period.
- Endpoint:
This comprehensive tutorial should provide a good foundation for understanding and implementing this messaging API. Remember to carefully consider the security implications of E2EE and key management. Good luck!