Complete API Documentation for Frontend Integration
Description: Registers a new user. After successful registration, an OTP will be sent to the provided email for verification.
{
"fullName": "John Deo",
"username": "johnDeo",
"email": "example@gmail.com",
"password": "StrongPassword!!@@",
"dob": "2005-10-09",
"location":"islamabad,pakistan"
}
location: "Islamabad, Pakistan" (city, country){
"message": "User registered successfully. Please verify your email."
}
// 400 Bad Request
{
"error": "Email already exists"
}
// 400 Bad Request
{
"error": "Password must contain at least one capital letter and special character"
}
// 400 Bad Request
{
"error": "User must be at least 18 years old"
}
Description: Verifies the OTP sent to the user's email during registration.
{
"email": "example@gmail.com",
"otp": 8967
}
{
"message": "Email verified successfully."
}
// 400 Bad Request
{
"error": "Invalid or expired OTP"
}
// 404 Not Found
{
"error": "User not found"
}
Description: Resends the email verification OTP to the user.
{
"email": "demo@yopmail.com"
}
{
"message": "Verification code resent successfully."
}
Description: Login or sign up via Google OAuth. Frontend handles Google login flow and sends the authorization code.
{
"code": "12fjfjf"
}
{
"message": "Additional information required",
"data": {
"_id": "690b15b6ac128979c08b9b84",
"email": "redkhan13@gmail.com",
"fullName": "Afridi Danial",
"isProfileComplete": false,
"isGoogleUser": true
}
}
{
"message": "Login successful.",
"token": "eyJhbGciOiJIUzI1NiIsInR5...",
"user": {
"_id": "690b15b6ac128979c08b9b84",
"fullName": "Afridi Danial",
"email": "redkhan13@gmail.com"
}
}
isProfileComplete: false, redirect the user to complete their profile with username and date of birth before proceeding.
Description: Completes profile information for users who registered with Google.
{
"username": "danialafridibwp",
"dob": "2002-10-12",
"location":"city,country"
}
{
"message": "Profile completed successfully.",
"data": {
"_id": "690b15b6ac128979c08b9b84",
"email": "redkhan13@gmail.com",
"username": "danialafridibwp",
"dob": "2002-10-12",
"token": "eyJhbGciOiJIUzI1NiIsInR5..."
}
}
location: "Islamabad, Pakistan" (city, country)
Description: Authenticates a user with email and password.
{
"email": "example@gmail.com",
"password": "StrongPassword!!@@"
}
{
"message": "Login successful.",
"token": "eyJhbGciOiJIUzI1NiIsInR5...",
"user": {
"_id": "690b15b6ac128979c08b9b84",
"fullName": "John Deo",
"email": "example@gmail.com"
}
}
// 401 Unauthorized
{
"error": "Invalid email or password"
}
// 403 Forbidden
{
"error": "Please verify your email before logging in"
}
Description: Fetches the profile details of the currently logged-in user.
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5...
{
"_id": "690b15b6ac128979c08b9b84",
"fullName": "John Deo",
"username": "johnDeo",
"email": "example@gmail.com",
"dob": "2005-10-09",
"isEmailVerified": true
}
// 401 Unauthorized
{
"error": "Invalid or expired token"
}
// 401 Unauthorized
{
"error": "No token provided"
}
Description: Initiates the password reset process by sending an OTP to the user's email.
{
"email": "example@gmail.com"
}
{
"message": "OTP sent to your email address."
}
Description: Verifies the OTP sent for password reset.
{
"email": "example@gmail.com",
"otp": 4495
}
{
"message": "OTP verified successfully."
}
Description: Resends the password reset OTP to the user's email.
{
"email": "example@gmail.com"
}
{
"message": "Forgot password OTP resent successfully."
}
Description: Resets the user's password after OTP verification.
{
"email": "example@gmail.com",
"password": "Demo@123"
}
{
"message": "Password reset successfully."
}
| Status Code | Error Type | Description |
|---|---|---|
| 400 | Bad Request | Invalid input data or validation error |
| 401 | Unauthorized | Missing or invalid authentication token |
| 403 | Forbidden | Email not verified or insufficient permissions |
| 404 | Not Found | Resource (user, endpoint) not found |
| 409 | Conflict | Email or username already exists |
| 429 | Too Many Requests | Rate limit exceeded (OTP requests) |
| 500 | Internal Server Error | Unexpected server error |
1. POST /auth/register β 2. POST /auth/verify-email-otp β 3. POST /auth/login
1. POST /auth/google/login β 2. PATCH /auth/complete-google-profile/:userId β 3. Access granted
1. POST /auth/google/login β 2. Access granted (token received)
1. POST /auth/forget-password β 2. POST /auth/verify-password-otp β 3. POST /auth/reset-password
Description: Retrieve the current authenticated userβs profile details.
Authorization: Bearer <token>
{
"_id": "680b15b6ac128979c08b9b84",
"fullName": "Demo User",
"username": "demo",
"bio": "This is the demo user of Hurcle Platform",
"image": "https://i.pravatar.cc/150?img=32",
"language": "English",
"privacy": "PUBLIC",
"notificationsEnabled": true
}
Description: Update user profile information such as fullName, username, bio, or image.
To update the profile image, follow the steps below before calling this endpoint.
{{LocalUrl}}/media/upload-multiple using FormData with the key name files.image: "uploadedImageUrl" in the PATCH payload below.{
"fullName": "Demo User",
"username": "demo",
"bio": "This is the demo user of Hurcle Platform",
"image": "https://cdn.hurcle.com/uploads/unique-image-url.jpg"
}
// Example JavaScript (FormData upload)
const formData = new FormData();
formData.append("files", selectedFile);
const uploadRes = await fetch("{{LocalUrl}}/media/upload-multiple", {
method: "POST",
body: formData
});
const data = await uploadRes.json();
const imageUrl = data[0]; // use this in your profile update
// Then call PATCH /user/me
await fetch("{{LocalUrl}}/user/me", {
method: "PATCH",
headers: {
"Authorization": "Bearer ",
"Content-Type": "application/json"
},
body: JSON.stringify({
fullName: "Demo User",
username: "demo",
bio: "This is the demo user of Hurcle Platform",
image: imageUrl
})
});
Description: Change the userβs password securely from the profile page.
{
"currentPassword": "Afridi4you!@@",
"newPassword": "Demo@123"
}
Description: Enable or disable user notifications.
{
"notificationsEnabled": true
}
Description: Update the userβs account privacy to PRIVATE or PUBLIC.
{
"privacy": "PRIVATE"
}
Description: Change user language preference.
{
"language": "French"
}
Description: Delete the current user account (token authentication required).
Authorization: Bearer <token>
Description: Create a new post with text content, optional media, visibility settings, and an optional location.
{{LocalUrl}}/media/upload-multiple using FormData with key files.media array when creating a post.{
"content": "Enjoying the sunset at the beach!",
"media": [
{
"url": "https://cdn.hurcle.com/uploads/beach-photo.jpg",
"type": "image"
}
],
"visibility": "public",
"location": {
"type": "Point",
"coordinates": [73.0479, 33.6844]
}
}
Description: Retrieve all public posts available to the authenticated user. Supports pagination.
?page=1&limit=10
Description: Admin-only endpoint for viewing all posts in the system.
Description: Get posts within a specific map area, defined by latitude and longitude bounds.
?north=33.70&south=33.60&east=73.10&west=73.00&limit=20&offset=0
Description: Get a specific post by its ID for the authenticated user.
Description: Retrieve all posts created by a specific user ID.
Description: Update an existing postβs content, visibility, or location.
β οΈ Note: Once a post is created, its attached media (images/videos) cannot be modified or replaced.
To change media, the post must be deleted and recreated.
{
"content": "Enjoying a day at the ground ποΈ!",
"visibility": "public",
"location": {
"type": "Point",
"coordinates": [72.11, 72.22]
}
}
/media/upload-multiple is not permitted in this endpoint.
The media field is read-only after post creation.
Description: Delete a specific post created by the authenticated user.
Description: Creates a one-to-one encrypted chat between the current user and another contact.
{
"participantId": "6911aabbccddeeff11223344"
}
{
"_id": "6912f8f7d2c3a2b4f1a2d3e4",
"type": "direct",
"members": ["690304822443a24bb8d62188", "6911aabbccddeeff11223344"],
"createdBy": "690304822443a24bb8d62188",
"createdAt": "2025-11-11T07:20:00Z"
}
Description: Creates a new group chat with multiple members and an optional group public key for encryption. The description field may include an explanation for image usage, such as:
{{LocalUrl}}/media/upload-multiple using FormData with the key name files. Then retrieve the uploaded image URL and pass it in the image field. Both description and image are optional.{
"name": "Team Alpha",
"members": ["690304822443a24bb8d62188", "6911aabbccddeeff11223344"],
"description": "Project discussion group with image upload",
"image": "https://your-uploaded-image-url.jpg"
}
{
"_id": "6912f8f7d2c3a2b4f1a2d3e4",
"type": "group",
"name": "Team Alpha",
"members": [
"690304822443a24bb8d62188",
"6911aabbccddeeff11223344"
],
"createdBy": "690304822443a24bb8d62188",
"createdAt": "2025-11-11T07:25:00Z"
}
Description: Fetches all chats (direct and group) the authenticated user is a member of.
[
{
"_id": "6911bebbab947721a2b45027",
"type": "direct",
"members": [
{ "_id": "690304822443a24bb8d62188", "username": "danial" },
{ "_id": "6911aabbccddeeff11223344", "username": "ahmad" }
]
},
{
"_id": "6911bebbab947721a2b45029",
"type": "group",
"name": "Team Alpha",
"members": [
"690304822443a24bb8d62188",
"6911aabbccddeeff11223344"
]
}
]
Description: Fetches all encrypted messages belonging to a specific chat.
[
{
"_id": "6912f12345a7efb100abc111",
"senderId": "690304822443a24bb8d62188",
"ciphertext": "U2FsdGVkX1+encryptedText==",
"encryptedKey": "RSA_KEY_STRING",
"iv": "randomIVstring",
"coordinates": { "lat": 31.5204, "lng": 74.3587 },
"createdAt": "2025-11-11T07:30:00Z"
}
]
Description:
Real-time encrypted chat communication over WebSockets.
All events require authentication via token (WsAuthGuard).
joinChat{
"event": "joinChat",
"data": "chatId"
}
β Joins a chat room if the authenticated user is a member. Membership is validated server-side.
sendMessageDirect Chat
{
"event": "sendMessage",
"data": {
"chatId": "6912f8f7d2c3a2b4f1a2d3e4",
"ciphertext": "BASE64_ENCRYPTED_TEXT",
"nonce": "BASE64_NONCE",
"coordinates": { "lat": 31.5204, "lng": 74.3587 },
"media": []
}
}
β Requires either ciphertext + nonce or media only.
Group Chat
{
"event": "sendMessage",
"data": {
"chatId": "6912f8f7d2c3a2b4f1a2d3e4",
"groupCiphertext": {
"keyId": "group-key-id",
"ciphertexts": {
"USER_ID_1": "ENCRYPTED_TEXT_1",
"USER_ID_2": "ENCRYPTED_TEXT_2"
}
},
"groupNonce": {
"nonces": {
"USER_ID_1": "NONCE_1",
"USER_ID_2": "NONCE_2"
}
},
"coordinates": { "lat": 31.5204, "lng": 74.3587 },
"media": []
}
}
β Requires valid group encryption payload or media. Encryption is per-recipient.
markMessagesRead{
"event": "markMessagesRead",
"data": {
"chatId": "6912f8f7d2c3a2b4f1a2d3e4"
}
}
β Marks all unread messages as read for the current user.
newMessageEmitted to all chat members when a message is sent successfully.
{
"message": "Message sent successfully",
"data": {
"_id": "6912f12345a7efb100abc111",
"chatId": "6912f8f7d2c3a2b4f1a2d3e4",
"ciphertext": "BASE64_ENCRYPTED_TEXT",
"nonce": "BASE64_NONCE",
"groupCiphertext": {
"keyId": "group-key-id",
"ciphertexts": {
"USER_ID_1": "ENCRYPTED_TEXT_1"
}
},
"groupNonce": {
"nonces": {
"USER_ID_1": "NONCE_1"
}
},
"media": [],
"coordinates": { "lat": 31.5204, "lng": 74.3587 },
"sender": {
"_id": "690304822443a24bb8d62188",
"username": "danial",
"fullName": "Danial Ahmed",
"image": "profile.jpg",
"userPublicKey": "RSA_PUBLIC_KEY"
},
"chat": {
"_id": "6912f8f7d2c3a2b4f1a2d3e4",
"type": "group",
"members": [
{
"_id": "690304822443a24bb8d62188",
"username": "danial",
"fullName": "Danial Ahmed",
"image": "profile.jpg",
"userPublicKey": "RSA_PUBLIC_KEY"
}
]
},
"createdAt": "2025-11-11T07:35:00Z"
}
}
messagesRead{
"chatId": "6912f8f7d2c3a2b4f1a2d3e4",
"readerId": "690304822443a24bb8d62188",
"modifiedCount": 5,
"remainingUnread": 0
}
newMessageError{
"message": "Message must include either encrypted text or media"
}