NAV
cURL JavaScript Dart

Introduction

Welcome to the Weellu API! You can use this API to access Weellu platform endpoints for messaging, channels, voice/video calls, social features, and more.

All API endpoints are served from:

https://api.weellu.com/api/v1/

We provide code examples in cURL, JavaScript, and Dart. You can view them in the dark area to the right, and switch between languages using the tabs above.

Authentication Overview

All authenticated requests require this header:

curl "https://api.weellu.com/api/v1/endpoint" \
  -H "Authorization: Bearer YOUR_TOKEN"
fetch('https://api.weellu.com/api/v1/endpoint', {
  headers: {
    'Authorization': 'Bearer YOUR_TOKEN'
  }
});
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/endpoint'),
  headers: {'Authorization': 'Bearer $token'},
);

Weellu uses Bearer tokens for authentication. There are two types of tokens:

Type How to Obtain Use Case
JWT Token POST /auth/login Full access to all user endpoints
API Token Request via Settings > API Integration access (requires admin approval)

Include your token in all API requests in a header:

Authorization: Bearer YOUR_TOKEN

Standard Response Format

All successful responses follow this structure:

{
  "code": 2000,
  "data": { },
  "msg": null
}

All API responses are wrapped in a standard envelope:

Field Type Description
code integer Status code: 2000 (success), 2100 (verify email sent), 4000 (failed), 5500 (client needs update)
data any The response payload (object, array, string, or null)
msg string/null Optional message

Pagination

Paginated responses follow this structure:

{
  "code": 2000,
  "data": {
    "docs": [ ],
    "totalDocs": 150,
    "totalPages": 8,
    "page": 1,
    "limit": 20,
    "hasNextPage": true,
    "hasPrevPage": false
  },
  "msg": null
}

Paginated endpoints accept these query parameters:

Parameter Type Default Description
page integer 1 Page number (1-indexed)
limit integer 20 Results per page (max 100)
lastId string - MongoDB ID for cursor-based pagination
pType string "page" Pagination type: page or id
createSort string "desc" Sort order: asc or desc

Common Field Abbreviations

The API uses short field names in responses for bandwidth efficiency:

Abbreviation Full Name Context
rId Room ID Messages, room members
sId Sender ID Messages
uId User ID Room members
pId Peer ID Single chats
cId Creator ID Room settings
mT Message Type Messages
c Content Message text
t Title Room title
img Image Thumbnails/avatars
rT Room Type Room classification
uC Unread Count Room members
sAt Seen At Message status
dAt Delivered At Message status
lId Local ID Client-generated message ID
isD Is Deleted Soft delete flag
isA Is Archived Archive flag
isM Is Muted Mute flag
isPin Is Pinned Pin flag

Room Types

Type Code Description
Single s One-on-one direct chat
Group g Group chat with multiple members
Broadcast b One-to-many broadcast channel
Project p Project management channel with tasks
Channel c Public channel
System sy System notifications

Platform Values

Value Description
Android Android mobile app
Ios iOS mobile app
Web Web browser client
Linux Linux desktop client
Mac macOS desktop client
Windows Windows desktop client
Other Other clients

Authentication

The Authentication API handles user registration, login, email verification, password resets, and session management. All endpoints are prefixed with /api/v1/auth.

Login

POST https://api.weellu.com/api/v1/auth/login

Authenticates a user with email and password. Returns a JWT access token on success. If the user's email is not yet verified, the server sends a new OTP and returns code 2100 instead of 2000.

Parameters

Parameter Type Required Description
email string Yes User's email address. Must be a valid email format. Trimmed automatically.
password string Yes User's password. Max length: 255.
platform string Yes Client platform. Enum: Android, Ios, Web, Linux, Mac, Windows, Other.
lang string Yes Language/locale code (e.g. en, ar).
mapInfo string Yes JSON-encoded string containing device location/map metadata.
deviceId string Yes Unique device identifier. Max length: 255. Trimmed automatically.
pushKey string No Firebase Cloud Messaging push token. Trimmed automatically.

Example Request

curl -X POST "https://api.weellu.com/api/v1/auth/login" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "john@example.com",
    "password": "securePass123",
    "platform": "Android",
    "lang": "en",
    "mapInfo": "{\"lat\":25.276987,\"lng\":55.296249}",
    "deviceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }'
const response = await fetch('https://api.weellu.com/api/v1/auth/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    email: 'john@example.com',
    password: 'securePass123',
    platform: 'Android',
    lang: 'en',
    mapInfo: '{"lat":25.276987,"lng":55.296249}',
    deviceId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
  })
});
const data = await response.json();
final response = await http.post(
  Uri.parse('https://api.weellu.com/api/v1/auth/login'),
  headers: {'Content-Type': 'application/json'},
  body: jsonEncode({
    'email': 'john@example.com',
    'password': 'securePass123',
    'platform': 'Android',
    'lang': 'en',
    'mapInfo': '{"lat":25.276987,"lng":55.296249}',
    'deviceId': 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
  }),
);

Example Response (200 - Verified User)

{
  "code": 2000,
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  },
  "msg": null
}

Example Response (200 - Unverified User, OTP Sent)

{
  "code": 2100,
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "message": "Verification code has been send to your email"
  },
  "msg": null
}

Example Error Response (400)

{
  "statusCode": 400,
  "message": "Invalid login credentials"
}

Register (Send OTP)

POST https://api.weellu.com/api/v1/auth/send-otp-register

Registers a new user account and sends an email verification OTP. Returns a JWT access token. If the email already exists but is unverified, a new OTP is sent instead. Supports an optional profile image upload via multipart form data.

Parameters

Parameter Type Required Description
email string Yes User's email address. Must be valid email format. Trimmed automatically.
fullName string Yes User's display name. Max length: 50. Trimmed automatically.
password string Yes User's password. Min length: 6, max length: 255.
platform string Yes Client platform. Enum: Android, Ios, Web, Linux, Mac, Windows, Other.
lang string Yes Language/locale code (e.g. en, ar).
mapInfo string Yes JSON-encoded string containing device location/map metadata.
deviceId string Yes Unique device identifier. Max length: 255. Trimmed automatically.
userName string No Desired username. 3-20 characters, alphanumeric and underscores only ([a-zA-Z0-9_]). Validated only if provided. Trimmed automatically.
pushKey string No Firebase Cloud Messaging push token. Trimmed automatically.
image file No Profile image file upload (multipart/form-data).

Example Request (JSON)

curl -X POST "https://api.weellu.com/api/v1/auth/send-otp-register" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane@example.com",
    "fullName": "Jane Smith",
    "password": "mySecure123",
    "platform": "Ios",
    "lang": "en",
    "mapInfo": "{\"lat\":40.712776,\"lng\":-74.005974}",
    "deviceId": "ios-device-uuid-12345"
  }'
const response = await fetch('https://api.weellu.com/api/v1/auth/send-otp-register', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    email: 'jane@example.com',
    fullName: 'Jane Smith',
    password: 'mySecure123',
    platform: 'Ios',
    lang: 'en',
    mapInfo: '{"lat":40.712776,"lng":-74.005974}',
    deviceId: 'ios-device-uuid-12345'
  })
});
const data = await response.json();
final response = await http.post(
  Uri.parse('https://api.weellu.com/api/v1/auth/send-otp-register'),
  headers: {'Content-Type': 'application/json'},
  body: jsonEncode({
    'email': 'jane@example.com',
    'fullName': 'Jane Smith',
    'password': 'mySecure123',
    'platform': 'Ios',
    'lang': 'en',
    'mapInfo': '{"lat":40.712776,"lng":-74.005974}',
    'deviceId': 'ios-device-uuid-12345',
  }),
);

Example Request (Multipart with Image)

curl -X POST "https://api.weellu.com/api/v1/auth/send-otp-register" \
  -F "email=jane@example.com" \
  -F "fullName=Jane Smith" \
  -F "password=mySecure123" \
  -F "platform=Ios" \
  -F "lang=en" \
  -F "mapInfo={\"lat\":40.712776,\"lng\":-74.005974}" \
  -F "deviceId=ios-device-uuid-12345" \
  -F "userName=janesmith" \
  -F "image=@/path/to/profile.jpg"

Example Response (201)

{
  "code": 2000,
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "message": "Verification code has been send to your email"
  },
  "msg": null
}

Example Error Response (400 - Email Exists)

{
  "statusCode": 400,
  "message": "User already in data base and verified"
}

Example Error Response (400 - Username Taken)

{
  "statusCode": 400,
  "message": "userName janesmith already exists please choose another one"
}

Verify Email

POST https://api.weellu.com/api/v1/auth/validate-email

Verifies a user's email address using the OTP code sent during registration. The code expires after 10 minutes.

Parameters

Parameter Type Required Description
email string Yes User's email address. Must be valid email format. Max length: 200. Trimmed automatically.
code number Yes The numeric OTP code received via email.

Example Request

curl -X POST "https://api.weellu.com/api/v1/auth/validate-email" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane@example.com",
    "code": 482910
  }'
const response = await fetch('https://api.weellu.com/api/v1/auth/validate-email', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    email: 'jane@example.com',
    code: 482910
  })
});
const data = await response.json();
final response = await http.post(
  Uri.parse('https://api.weellu.com/api/v1/auth/validate-email'),
  headers: {'Content-Type': 'application/json'},
  body: jsonEncode({
    'email': 'jane@example.com',
    'code': 482910,
  }),
);

Example Response (200)

{
  "code": 2000,
  "data": "Email has been verified successfully",
  "msg": null
}

Example Error Response (400 - Already Verified)

{
  "statusCode": 400,
  "message": "User already verified"
}

Example Error Response (400 - Expired Code)

{
  "statusCode": 400,
  "message": "Code has been expired"
}

Example Error Response (400 - Invalid Code)

{
  "statusCode": 400,
  "message": "Invalid code !"
}

Check Username Availability

GET https://api.weellu.com/api/v1/auth/check-user-name/:userName

Checks whether a given username is already taken. Useful for real-time validation during registration.

Parameters

Parameter Type Required Description
userName string Yes The username to check. URL path parameter. 3-20 characters, alphanumeric and underscores only ([a-zA-Z0-9_]).

Example Request

curl -X GET "https://api.weellu.com/api/v1/auth/check-user-name/janesmith"
const response = await fetch('https://api.weellu.com/api/v1/auth/check-user-name/janesmith');
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/auth/check-user-name/janesmith'),
);

Example Response (200 - Available)

{
  "code": 2000,
  "data": {
    "isExists": false
  },
  "msg": null
}

Example Response (200 - Taken)

{
  "code": 2000,
  "data": {
    "isExists": true
  },
  "msg": null
}

Request Password Reset (Send OTP)

POST https://api.weellu.com/api/v1/auth/send-otp-reset-password

Sends a password reset OTP to the specified email address. The user must have a registered account.

Parameters

Parameter Type Required Description
email string Yes The email address of the account to reset. Must be a registered email.

Example Request

curl -X POST "https://api.weellu.com/api/v1/auth/send-otp-reset-password" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "john@example.com"
  }'
const response = await fetch('https://api.weellu.com/api/v1/auth/send-otp-reset-password', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    email: 'john@example.com'
  })
});
const data = await response.json();
final response = await http.post(
  Uri.parse('https://api.weellu.com/api/v1/auth/send-otp-reset-password'),
  headers: {'Content-Type': 'application/json'},
  body: jsonEncode({
    'email': 'john@example.com',
  }),
);

Example Response (201)

{
  "code": 2000,
  "data": "Password reset code has been send to your email",
  "msg": null
}

Example Error Response (400)

{
  "statusCode": 400,
  "message": "Email is required"
}

Complete Password Reset

POST https://api.weellu.com/api/v1/auth/verify-and-reset-password

Verifies the password reset OTP and sets a new password. The code must have been requested via the /auth/send-otp-reset-password endpoint and must not be expired.

Parameters

Parameter Type Required Description
email string Yes The account email address. Must be valid email format. Max length: 200.
code string Yes The numeric OTP code received via email. Must be a numeric string. Max length: 6.
newPassword string Yes The new password to set.

Example Request

curl -X POST "https://api.weellu.com/api/v1/auth/verify-and-reset-password" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "john@example.com",
    "code": "482910",
    "newPassword": "myNewSecurePass456"
  }'
const response = await fetch('https://api.weellu.com/api/v1/auth/verify-and-reset-password', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    email: 'john@example.com',
    code: '482910',
    newPassword: 'myNewSecurePass456'
  })
});
const data = await response.json();
final response = await http.post(
  Uri.parse('https://api.weellu.com/api/v1/auth/verify-and-reset-password'),
  headers: {'Content-Type': 'application/json'},
  body: jsonEncode({
    'email': 'john@example.com',
    'code': '482910',
    'newPassword': 'myNewSecurePass456',
  }),
);

Example Response (201)

{
  "code": 2000,
  "data": "Password has been reset successfully",
  "msg": null
}

Example Error Response (400 - Expired Code)

{
  "statusCode": 400,
  "message": "Code has been expired"
}

Example Error Response (400 - Invalid Code)

{
  "statusCode": 400,
  "message": "Invalid code !"
}

Logout

POST https://api.weellu.com/api/v1/auth/logout

Logs out the current device or all devices. Requires authentication. When logging out from all devices, the user's password is required for security verification.

Parameters

Parameter Type Required Description
logoutFromAll boolean Yes If true, logs out from all devices. If false, logs out only the current device.
password string Conditional Required when logoutFromAll is true. The user's current password for verification.

Headers

Header Required Description
Authorization Yes Bearer token. Format: Bearer <accessToken>

Example Request (Current Device)

curl -X POST "https://api.weellu.com/api/v1/auth/logout" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -d '{
    "logoutFromAll": false
  }'
const response = await fetch('https://api.weellu.com/api/v1/auth/logout', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIs...'
  },
  body: JSON.stringify({
    logoutFromAll: false
  })
});
const data = await response.json();
final response = await http.post(
  Uri.parse('https://api.weellu.com/api/v1/auth/logout'),
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIs...',
  },
  body: jsonEncode({
    'logoutFromAll': false,
  }),
);

Example Request (All Devices)

curl -X POST "https://api.weellu.com/api/v1/auth/logout" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -d '{
    "logoutFromAll": true,
    "password": "securePass123"
  }'

Example Response (200 - Current Device)

{
  "code": 2000,
  "data": "Device has been logout",
  "msg": null
}

Example Response (200 - All Devices)

{
  "code": 2000,
  "data": "Device has been logout from all devices",
  "msg": null
}

Example Error Response (400 - Wrong Password)

{
  "statusCode": 400,
  "message": "Invalid login credentials"
}

Example Error Response (401 - Unauthorized)

{
  "statusCode": 401,
  "message": "Unauthorized"
}

API Tokens

The API Tokens endpoints allow authenticated users to request, view, and cancel personal API tokens. API tokens are used for programmatic access to the Weellu platform (e.g., integrations, bots). All endpoints require authentication and are prefixed with /api/v1/user-api-token.

Token requests go through an approval workflow: a newly created token starts in pending status and must be approved by an administrator before it becomes active.

Token Statuses

Status Description
pending Token has been requested and is awaiting admin approval.
approved Token has been approved and is active for use.
rejected Token request has been rejected by an admin.
cancelled Token has been cancelled by the user.

Request New API Token

POST https://api.weellu.com/api/v1/user-api-token

Requests a new API token for the authenticated user. Each user can only have one token at a time. The token is created with pending status and must be approved by an administrator.

Headers

Header Required Description
Authorization Yes Bearer token. Format: Bearer <accessToken>

Parameters

Parameter Type Required Description
requestData string No Optional free-text field describing the intended use of the token (e.g., integration name, purpose).

Example Request

curl -X POST "https://api.weellu.com/api/v1/user-api-token" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -d '{
    "requestData": "Bot integration for automated customer support"
  }'
const response = await fetch('https://api.weellu.com/api/v1/user-api-token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIs...'
  },
  body: JSON.stringify({
    requestData: 'Bot integration for automated customer support'
  })
});
const data = await response.json();
final response = await http.post(
  Uri.parse('https://api.weellu.com/api/v1/user-api-token'),
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIs...',
  },
  body: jsonEncode({
    'requestData': 'Bot integration for automated customer support',
  }),
);

Example Response (201)

{
  "code": 2000,
  "data": {
    "_id": "660a1b2c3d4e5f6789012345",
    "userId": "65f9a8b7c6d5e4f3a2b10987",
    "token": "660a1b2c3d4e5f6789abcdef",
    "requestData": "Bot integration for automated customer support",
    "status": "pending",
    "createdAt": "2026-03-18T14:30:00.000Z"
  },
  "msg": null
}

Example Error Response (400 - Token Already Exists)

{
  "statusCode": 400,
  "message": "User already has a token"
}

Example Error Response (401 - Unauthorized)

{
  "statusCode": 401,
  "message": "Unauthorized"
}

Get My API Token Status

GET https://api.weellu.com/api/v1/user-api-token

Retrieves the current user's API token and its status. Returns null if no token exists.

Headers

Header Required Description
Authorization Yes Bearer token. Format: Bearer <accessToken>

Parameters

None.

Example Request

curl -X GET "https://api.weellu.com/api/v1/user-api-token" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
const response = await fetch('https://api.weellu.com/api/v1/user-api-token', {
  headers: {
    'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIs...'
  }
});
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/user-api-token'),
  headers: {
    'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIs...',
  },
);

Example Response (200 - Token Exists)

{
  "code": 2000,
  "data": {
    "_id": "660a1b2c3d4e5f6789012345",
    "userId": "65f9a8b7c6d5e4f3a2b10987",
    "token": "660a1b2c3d4e5f6789abcdef",
    "requestData": "Bot integration for automated customer support",
    "status": "approved",
    "createdAt": "2026-03-18T14:30:00.000Z"
  },
  "msg": null
}

Example Response (200 - No Token)

{
  "code": 2000,
  "data": null,
  "msg": null
}

Example Error Response (401 - Unauthorized)

{
  "statusCode": 401,
  "message": "Unauthorized"
}

Cancel My API Token

DELETE https://api.weellu.com/api/v1/user-api-token

Permanently deletes the current user's API token. This works regardless of the token's current status (pending, approved, rejected). After cancellation, the user can request a new token.

Headers

Header Required Description
Authorization Yes Bearer token. Format: Bearer <accessToken>

Parameters

None.

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/user-api-token" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
const response = await fetch('https://api.weellu.com/api/v1/user-api-token', {
  method: 'DELETE',
  headers: {
    'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIs...'
  }
});
const data = await response.json();
final response = await http.delete(
  Uri.parse('https://api.weellu.com/api/v1/user-api-token'),
  headers: {
    'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIs...',
  },
);

Example Response (200 - Token Deleted)

{
  "code": 2000,
  "data": {
    "_id": "660a1b2c3d4e5f6789012345",
    "userId": "65f9a8b7c6d5e4f3a2b10987",
    "token": "660a1b2c3d4e5f6789abcdef",
    "requestData": "Bot integration for automated customer support",
    "status": "pending",
    "createdAt": "2026-03-18T14:30:00.000Z"
  },
  "msg": null
}

Example Response (200 - No Token to Delete)

{
  "code": 2000,
  "data": null,
  "msg": null
}

Example Error Response (401 - Unauthorized)

{
  "statusCode": 401,
  "message": "Unauthorized"
}

Profile

Profile management endpoints for the authenticated user. All endpoints require a valid Authorization: Bearer TOKEN header.

Enums Reference

MediaAutoDownloadOption

Value Description
images Auto-download images
videos Auto-download videos
files Auto-download files
voices Auto-download voice messages

UserRole

Value Description
assistant Virtual assistant role
admin Admin role
superAdmin Super admin role
business Business role
prime Prime user role

BusinessStatus

Value Description
active Business is active
notActive Business is deactivated
none No business profile

Get My Profile

GET https://api.weellu.com/api/v1/profile/

Returns the authenticated user's profile with follower/following counts, active story count, and current device info.

Parameters

No parameters required.

Example Request

curl "https://api.weellu.com/api/v1/profile/" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch("https://api.weellu.com/api/v1/profile/", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  }
});
const data = await response.json();
import 'package:chopper/chopper.dart';

final response = await chopperClient.get(
  Uri.parse('/api/v1/profile/'),
  headers: {'Authorization': 'Bearer $token'},
);

Example Response

{
  "data": {
    "followersCount": 142,
    "followingCount": 87,
    "postsCount": 3,
    "newUpdateNote": null,
    "me": {
      "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
      "email": "john@example.com",
      "fullName": "John Doe",
      "fullNameEn": "John Doe",
      "userName": "johndoe",
      "userType": "normal",
      "businessStatus": "none",
      "roles": [],
      "userImages": {
        "originalImage": "https://cdn.weellu.com/users/64f1a2b3/original.jpg",
        "chatImage": "https://cdn.weellu.com/users/64f1a2b3/chat.jpg",
        "smallImage": "https://cdn.weellu.com/users/64f1a2b3/small.jpg"
      },
      "mediaAutoDownload": {
        "wifi": ["images", "videos", "files", "voices"],
        "mobile": ["images", "videos", "files", "voices"]
      }
    },
    "currentDevice": {
      "_id": "64f1a2b3c4d5e6f7a8b9c0d2",
      "platform": "android",
      "lang": "en",
      "clintVersion": "2.1.0+45"
    }
  }
}

Get Peer Profile

GET https://api.weellu.com/api/v1/profile/:id

Returns another user's public profile with follower/following counts and whether you follow them.

URL Parameters

Parameter Type Required Description
id string Yes MongoDB ObjectId of the target user

Example Request

curl "https://api.weellu.com/api/v1/profile/64f1a2b3c4d5e6f7a8b9c0d1" \
  -H "Authorization: Bearer YOUR_TOKEN"
const userId = "64f1a2b3c4d5e6f7a8b9c0d1";
const response = await fetch(`https://api.weellu.com/api/v1/profile/${userId}`, {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  }
});
const data = await response.json();
final userId = '64f1a2b3c4d5e6f7a8b9c0d1';
final response = await chopperClient.get(
  Uri.parse('/api/v1/profile/$userId'),
  headers: {'Authorization': 'Bearer $token'},
);

Example Response

{
  "data": {
    "user": {
      "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
      "fullName": "Jane Smith",
      "email": "jane@example.com",
      "userType": "normal",
      "userImages": {
        "originalImage": "https://cdn.weellu.com/users/64f1a2b3/original.jpg",
        "chatImage": "https://cdn.weellu.com/users/64f1a2b3/chat.jpg",
        "smallImage": "https://cdn.weellu.com/users/64f1a2b3/small.jpg"
      }
    },
    "isFollowing": true,
    "followersCount": 312,
    "followingCount": 156,
    "postsCount": 7
  }
}

Get App Configuration

GET https://api.weellu.com/api/v1/profile/app-config

Returns the application configuration settings.

Parameters

No parameters required.

Example Request

curl "https://api.weellu.com/api/v1/profile/app-config" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch("https://api.weellu.com/api/v1/profile/app-config", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  }
});
const data = await response.json();
final response = await chopperClient.get(
  Uri.parse('/api/v1/profile/app-config'),
  headers: {'Authorization': 'Bearer $token'},
);

Example Response

{
  "data": {
    "maxGroupMembers": 512,
    "maxBroadcastMembers": 512,
    "maxProjectMembers": 5000,
    "maxFileSize": 104857600,
    "supportedMediaTypes": ["image/jpeg", "image/png", "video/mp4", "audio/mpeg"]
  }
}

Search Users

GET https://api.weellu.com/api/v1/profile/users/v2

Search for users by name. Excludes blocked users. When roomId is provided, results are scoped to that room's members (useful for @mention autocomplete).

Query Parameters

Parameter Type Required Description
search string No Search term to match against fullName or fullNameEn
limit number No Number of results per page (default: 20, must be > 0)
page number No Page number (default: 1, must be > 0)
roomId string No MongoDB ObjectId of a room to scope results to room members only

Example Request

curl "https://api.weellu.com/api/v1/profile/users/v2?search=john&limit=10&page=1" \
  -H "Authorization: Bearer YOUR_TOKEN"
const params = new URLSearchParams({
  search: "john",
  limit: "10",
  page: "1"
});
const response = await fetch(`https://api.weellu.com/api/v1/profile/users/v2?${params}`, {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  }
});
const data = await response.json();
final response = await chopperClient.get(
  Uri.parse('/api/v1/profile/users/v2?search=john&limit=10&page=1'),
  headers: {'Authorization': 'Bearer $token'},
);

Example Response

{
  "data": {
    "docs": [
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
        "fullName": "John Doe",
        "fullNameEn": "John Doe",
        "userImages": {
          "originalImage": "https://cdn.weellu.com/users/64f1a2b3/original.jpg",
          "chatImage": "https://cdn.weellu.com/users/64f1a2b3/chat.jpg",
          "smallImage": "https://cdn.weellu.com/users/64f1a2b3/small.jpg"
        }
      }
    ],
    "totalDocs": 1,
    "totalPages": 1,
    "page": 1,
    "hasNextPage": false
  }
}

Update Name

PATCH https://api.weellu.com/api/v1/profile/name

Updates the authenticated user's display name. Also propagates the change to all room memberships.

Body Parameters

Parameter Type Required Description
fullName string Yes New display name. Must not be empty. Maximum 50 characters.

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/profile/name" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"fullName": "John Smith"}'
const response = await fetch("https://api.weellu.com/api/v1/profile/name", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ fullName: "John Smith" })
});
const data = await response.json();
final response = await chopperClient.patch(
  Uri.parse('/api/v1/profile/name'),
  headers: {
    'Authorization': 'Bearer $token',
    'Content-Type': 'application/json',
  },
  body: jsonEncode({'fullName': 'John Smith'}),
);

Example Response

{
  "data": "Name has been changed successfully"
}

Update Username

PATCH https://api.weellu.com/api/v1/profile/user-name

Updates the authenticated user's unique username. The username is stored in lowercase.

Body Parameters

Parameter Type Required Description
userName string Yes New username. Must be 3-20 characters, alphanumeric and underscores only (/^[a-zA-Z0-9_]+$/). Must be unique across all users.

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/profile/user-name" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"userName": "john_doe_99"}'
const response = await fetch("https://api.weellu.com/api/v1/profile/user-name", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ userName: "john_doe_99" })
});
const data = await response.json();
final response = await chopperClient.patch(
  Uri.parse('/api/v1/profile/user-name'),
  headers: {
    'Authorization': 'Bearer $token',
    'Content-Type': 'application/json',
  },
  body: jsonEncode({'userName': 'john_doe_99'}),
);

Example Response

{
  "data": "Done"
}

Update Email

PATCH https://api.weellu.com/api/v1/profile/email

Updates the authenticated user's email address. Requires current password for verification.

Body Parameters

Parameter Type Required Description
newEmail string Yes New email address. Must be a valid email format. Maximum 200 characters. Must not already be in use.
currentPassword string Yes Current account password for verification. Must not be empty.

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/profile/email" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"newEmail": "newemail@example.com", "currentPassword": "MyP@ssw0rd"}'
const response = await fetch("https://api.weellu.com/api/v1/profile/email", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    newEmail: "newemail@example.com",
    currentPassword: "MyP@ssw0rd"
  })
});
const data = await response.json();
final response = await chopperClient.patch(
  Uri.parse('/api/v1/profile/email'),
  headers: {
    'Authorization': 'Bearer $token',
    'Content-Type': 'application/json',
  },
  body: jsonEncode({
    'newEmail': 'newemail@example.com',
    'currentPassword': 'MyP@ssw0rd',
  }),
);

Example Response

{
  "data": "Email updated successfully."
}

Update Password

PATCH https://api.weellu.com/api/v1/profile/password

Changes the authenticated user's password. Optionally logs out all other devices.

Body Parameters

Parameter Type Required Description
oldPassword string Yes Current password for verification. Must not be empty.
newPassword string Yes New password. Minimum 6 characters, maximum 255 characters.
logoutFromAll boolean Yes If true, all other device sessions are terminated.

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/profile/password" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"oldPassword": "OldP@ss123", "newPassword": "NewStr0ng!Pass", "logoutFromAll": false}'
const response = await fetch("https://api.weellu.com/api/v1/profile/password", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    oldPassword: "OldP@ss123",
    newPassword: "NewStr0ng!Pass",
    logoutFromAll: false
  })
});
const data = await response.json();
final response = await chopperClient.patch(
  Uri.parse('/api/v1/profile/password'),
  headers: {
    'Authorization': 'Bearer $token',
    'Content-Type': 'application/json',
  },
  body: jsonEncode({
    'oldPassword': 'OldP@ss123',
    'newPassword': 'NewStr0ng!Pass',
    'logoutFromAll': false,
  }),
);

Example Response

{
  "data": "Password changed successfully"
}

Upload Profile Image

PATCH https://api.weellu.com/api/v1/profile/image

Uploads a new profile image. The image is processed and stored in multiple sizes. Also propagates to all room memberships.

Body Parameters

Parameter Type Required Description
file file Yes Image file (multipart/form-data). Supported formats: JPEG, PNG, WebP.

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/profile/image" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "file=@/path/to/photo.jpg"
const formData = new FormData();
formData.append("file", fileInput.files[0]);

const response = await fetch("https://api.weellu.com/api/v1/profile/image", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  },
  body: formData
});
const data = await response.json();
import 'package:http/http.dart' as http;

final request = http.MultipartRequest(
  'PATCH',
  Uri.parse('https://api.weellu.com/api/v1/profile/image'),
);
request.headers['Authorization'] = 'Bearer $token';
request.files.add(await http.MultipartFile.fromPath('file', '/path/to/photo.jpg'));
final response = await request.send();

Example Response

{
  "data": "Image has been changed successfully"
}

Update Language

PATCH https://api.weellu.com/api/v1/profile/lang

Updates the preferred language for the current device session.

Body Parameters

Parameter Type Required Description
lang string Yes Language code (e.g. "en", "pt", "ar"). Must not be empty.

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/profile/lang" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"lang": "pt"}'
const response = await fetch("https://api.weellu.com/api/v1/profile/lang", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ lang: "pt" })
});
const data = await response.json();
final response = await chopperClient.patch(
  Uri.parse('/api/v1/profile/lang'),
  headers: {
    'Authorization': 'Bearer $token',
    'Content-Type': 'application/json',
  },
  body: jsonEncode({'lang': 'pt'}),
);

Example Response

{
  "data": "Language has been updated"
}

Update Media Auto-Download Settings

PATCH https://api.weellu.com/api/v1/profile/media-download

Configures which media types are automatically downloaded on WiFi and/or mobile networks. At least one of wifi or mobile must be provided.

Body Parameters

Parameter Type Required Description
wifi string[] No Array of media types to auto-download on WiFi. Valid values: "images", "videos", "files", "voices". At least one of wifi or mobile is required.
mobile string[] No Array of media types to auto-download on mobile data. Valid values: "images", "videos", "files", "voices". At least one of wifi or mobile is required.

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/profile/media-download" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"wifi": ["images", "videos", "files", "voices"], "mobile": ["images"]}'
const response = await fetch("https://api.weellu.com/api/v1/profile/media-download", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    wifi: ["images", "videos", "files", "voices"],
    mobile: ["images"]
  })
});
const data = await response.json();
final response = await chopperClient.patch(
  Uri.parse('/api/v1/profile/media-download'),
  headers: {
    'Authorization': 'Bearer $token',
    'Content-Type': 'application/json',
  },
  body: jsonEncode({
    'wifi': ['images', 'videos', 'files', 'voices'],
    'mobile': ['images'],
  }),
);

Example Response

{
  "data": {
    "wifi": ["images", "videos", "files", "voices"],
    "mobile": ["images"]
  }
}

Set Chat Wallpaper URL

PATCH https://api.weellu.com/api/v1/profile/chat-wallpaper

Sets the chat wallpaper to a URL string. Emits a v1OnChatWallpaperChanged socket event to all connected devices.

Body Parameters

Parameter Type Required Description
chatWallpaper string No URL or S3 key of the wallpaper image. Pass null or omit to remove wallpaper.

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/profile/chat-wallpaper" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"chatWallpaper": "https://cdn.weellu.com/wallpapers/sunset.jpg"}'
const response = await fetch("https://api.weellu.com/api/v1/profile/chat-wallpaper", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    chatWallpaper: "https://cdn.weellu.com/wallpapers/sunset.jpg"
  })
});
const data = await response.json();
final response = await chopperClient.patch(
  Uri.parse('/api/v1/profile/chat-wallpaper'),
  headers: {
    'Authorization': 'Bearer $token',
    'Content-Type': 'application/json',
  },
  body: jsonEncode({
    'chatWallpaper': 'https://cdn.weellu.com/wallpapers/sunset.jpg',
  }),
);

Example Response

{
  "data": {
    "chatWallpaper": "https://cdn.weellu.com/wallpapers/sunset.jpg"
  }
}

Upload Chat Wallpaper Image

POST https://api.weellu.com/api/v1/profile/chat-wallpaper

Uploads an image file as the chat wallpaper. The file is stored in S3 and the URL is saved to the user profile. Emits a v1OnChatWallpaperChanged socket event to all connected devices.

Body Parameters

Parameter Type Required Description
file file Yes Image file (multipart/form-data). Supported formats: JPEG, PNG, WebP.

Example Request

curl -X POST "https://api.weellu.com/api/v1/profile/chat-wallpaper" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "file=@/path/to/wallpaper.jpg"
const formData = new FormData();
formData.append("file", fileInput.files[0]);

const response = await fetch("https://api.weellu.com/api/v1/profile/chat-wallpaper", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  },
  body: formData
});
const data = await response.json();
import 'package:http/http.dart' as http;

final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/profile/chat-wallpaper'),
);
request.headers['Authorization'] = 'Bearer $token';
request.files.add(await http.MultipartFile.fromPath('file', '/path/to/wallpaper.jpg'));
final response = await request.send();

Example Response

{
  "data": {
    "chatWallpaper": "media/64f1a2b3c4d5e6f7a8b9c0d1/wallpaper_1710432000.jpg"
  }
}

Check App Version

POST https://api.weellu.com/api/v1/profile/version/check

Checks if the client app version is up to date. Compares the client's semantic version and build number against the latest server version for the current platform.

Body Parameters

Parameter Type Required Description
semVer string Yes Semantic version string (e.g. "2.1.0"). Must be valid semver format.
buildNumber number Yes Build number (e.g. 45).

Example Request

curl -X POST "https://api.weellu.com/api/v1/profile/version/check" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"semVer": "2.1.0", "buildNumber": 45}'
const response = await fetch("https://api.weellu.com/api/v1/profile/version/check", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    semVer: "2.1.0",
    buildNumber: 45
  })
});
const data = await response.json();
final response = await chopperClient.post(
  Uri.parse('/api/v1/profile/version/check'),
  headers: {
    'Authorization': 'Bearer $token',
    'Content-Type': 'application/json',
  },
  body: jsonEncode({
    'semVer': '2.1.0',
    'buildNumber': 45,
  }),
);

Example Response

{
  "data": {
    "isNeedUpdates": true,
    "isCritical": false,
    "clientVersion": "2.1.0",
    "clientBuild": 45,
    "notes": "Bug fixes and performance improvements",
    "serverVersion": "2.2.0",
    "serverBuild": 50,
    "platform": "android"
  }
}

Delete Account

DELETE https://api.weellu.com/api/v1/profile/

Soft-deletes the authenticated user's account by setting deletedAt to the current timestamp.

Parameters

No parameters required.

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/profile/" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch("https://api.weellu.com/api/v1/profile/", {
  method: "DELETE",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  }
});
const data = await response.json();
final response = await chopperClient.delete(
  Uri.parse('/api/v1/profile/'),
  headers: {'Authorization': 'Bearer $token'},
);

Example Response

{
  "data": "account deleted !"
}

Update Last Visit

PATCH https://api.weellu.com/api/v1/profile/visit

Increments the visit counter for the current device session.

Parameters

No parameters required.

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/profile/visit" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch("https://api.weellu.com/api/v1/profile/visit", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  }
});
const data = await response.json();
final response = await chopperClient.patch(
  Uri.parse('/api/v1/profile/visit'),
  headers: {'Authorization': 'Bearer $token'},
);

Example Response

{
  "data": "Done"
}

Toggle Virtual Assistant

PATCH https://api.weellu.com/api/v1/profile/assistant

Enables or disables the virtual assistant role for the authenticated user. When enabled, adds the assistant role. When disabled, removes the role and clears the assistId.

Body Parameters

Parameter Type Required Description
isEnable boolean Yes true to enable the virtual assistant role, false to disable it.

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/profile/assistant" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"isEnable": true}'
const response = await fetch("https://api.weellu.com/api/v1/profile/assistant", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ isEnable: true })
});
const data = await response.json();
final response = await chopperClient.patch(
  Uri.parse('/api/v1/profile/assistant'),
  headers: {
    'Authorization': 'Bearer $token',
    'Content-Type': 'application/json',
  },
  body: jsonEncode({'isEnable': true}),
);

Example Response

{
  "data": "Role added"
}

Get Peer Last Seen

GET https://api.weellu.com/api/v1/profile/users/:peerId/last-seen

Returns the last seen timestamp for a specific user.

URL Parameters

Parameter Type Required Description
peerId string Yes MongoDB ObjectId of the target user

Example Request

curl "https://api.weellu.com/api/v1/profile/users/64f1a2b3c4d5e6f7a8b9c0d1/last-seen" \
  -H "Authorization: Bearer YOUR_TOKEN"
const peerId = "64f1a2b3c4d5e6f7a8b9c0d1";
const response = await fetch(`https://api.weellu.com/api/v1/profile/users/${peerId}/last-seen`, {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  }
});
const data = await response.json();
final peerId = '64f1a2b3c4d5e6f7a8b9c0d1';
final response = await chopperClient.get(
  Uri.parse('/api/v1/profile/users/$peerId/last-seen'),
  headers: {'Authorization': 'Bearer $token'},
);

Example Response

{
  "data": "2026-03-18T14:30:00.000Z"
}

Register Push Key

POST https://api.weellu.com/api/v1/profile/push

Registers a push notification key and/or VoIP key for the current device. At least one of pushKey or voipKey must be provided.

Body Parameters

Parameter Type Required Description
pushKey string No FCM push notification token. At least one of pushKey or voipKey is required.
voipKey string No VoIP push notification token (for iOS CallKit). At least one of pushKey or voipKey is required.

Example Request

curl -X POST "https://api.weellu.com/api/v1/profile/push" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"pushKey": "dGVzdC1mY20tdG9rZW4tZXhhbXBsZQ==", "voipKey": "dm9pcC10b2tlbi1leGFtcGxl"}'
const response = await fetch("https://api.weellu.com/api/v1/profile/push", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    pushKey: "dGVzdC1mY20tdG9rZW4tZXhhbXBsZQ==",
    voipKey: "dm9pcC10b2tlbi1leGFtcGxl"
  })
});
const data = await response.json();
final response = await chopperClient.post(
  Uri.parse('/api/v1/profile/push'),
  headers: {
    'Authorization': 'Bearer $token',
    'Content-Type': 'application/json',
  },
  body: jsonEncode({
    'pushKey': 'dGVzdC1mY20tdG9rZW4tZXhhbXBsZQ==',
    'voipKey': 'dm9pcC10b2tlbi1leGFtcGxl',
  }),
);

Example Response

{
  "data": "PushKey added"
}

Add FCM Token (Deprecated)

POST https://api.weellu.com/api/v1/profile/fcm

Registers an FCM push notification token for the current device.

Body Parameters

Parameter Type Required Description
pushKey string Yes FCM push notification token.

Example Request

curl -X POST "https://api.weellu.com/api/v1/profile/fcm" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"pushKey": "dGVzdC1mY20tdG9rZW4tZXhhbXBsZQ=="}'
const response = await fetch("https://api.weellu.com/api/v1/profile/fcm", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ pushKey: "dGVzdC1mY20tdG9rZW4tZXhhbXBsZQ==" })
});
const data = await response.json();
final response = await chopperClient.post(
  Uri.parse('/api/v1/profile/fcm'),
  headers: {
    'Authorization': 'Bearer $token',
    'Content-Type': 'application/json',
  },
  body: jsonEncode({'pushKey': 'dGVzdC1mY20tdG9rZW4tZXhhbXBsZQ=='}),
);

Example Response

{
  "data": "PushKey added"
}

Update FCM Token

PATCH https://api.weellu.com/api/v1/profile/fcm

Updates the FCM push notification token for the current device.

Body Parameters

Parameter Type Required Description
pushKey string Yes Updated FCM push notification token. Must not be empty.

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/profile/fcm" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"pushKey": "bmV3LWZjbS10b2tlbi1leGFtcGxl"}'
const response = await fetch("https://api.weellu.com/api/v1/profile/fcm", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ pushKey: "bmV3LWZjbS10b2tlbi1leGFtcGxl" })
});
const data = await response.json();
final response = await chopperClient.patch(
  Uri.parse('/api/v1/profile/fcm'),
  headers: {
    'Authorization': 'Bearer $token',
    'Content-Type': 'application/json',
  },
  body: jsonEncode({'pushKey': 'bmV3LWZjbS10b2tlbi1leGFtcGxl'}),
);

Example Response

{
  "data": "updated!"
}

Delete FCM Token

DELETE https://api.weellu.com/api/v1/profile/fcm

Removes the FCM push notification token from the current device. The device will no longer receive push notifications.

Parameters

No parameters required.

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/profile/fcm" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch("https://api.weellu.com/api/v1/profile/fcm", {
  method: "DELETE",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  }
});
const data = await response.json();
final response = await chopperClient.delete(
  Uri.parse('/api/v1/profile/fcm'),
  headers: {'Authorization': 'Bearer $token'},
);

Example Response

{
  "data": "Fcm deleted"
}

Create Quick Message

POST https://api.weellu.com/api/v1/profile/quick-message

Creates a text shortcut (quick message) for fast message insertion.

Body Parameters

Parameter Type Required Description
shortcut string Yes Shortcut trigger text (e.g. /hello). Must not be empty.
desc string Yes The full message text that replaces the shortcut. Must not be empty.

Example Request

curl -X POST "https://api.weellu.com/api/v1/profile/quick-message" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"shortcut": "/hello", "desc": "Hello! How can I help you today?"}'
const response = await fetch("https://api.weellu.com/api/v1/profile/quick-message", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    shortcut: "/hello",
    desc: "Hello! How can I help you today?"
  })
});
const data = await response.json();
final response = await chopperClient.post(
  Uri.parse('/api/v1/profile/quick-message'),
  headers: {
    'Authorization': 'Bearer $token',
    'Content-Type': 'application/json',
  },
  body: jsonEncode({
    'shortcut': '/hello',
    'desc': 'Hello! How can I help you today?',
  }),
);

Example Response

{
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d3",
    "userId": "64f1a2b3c4d5e6f7a8b9c0d1",
    "shortcut": "/hello",
    "desc": "Hello! How can I help you today?",
    "createdAt": "2026-03-18T10:00:00.000Z",
    "updatedAt": "2026-03-18T10:00:00.000Z"
  }
}

List Quick Messages

GET https://api.weellu.com/api/v1/profile/quick-message

Returns a paginated list of the authenticated user's quick messages. Optionally filter by shortcut text.

Query Parameters

Parameter Type Required Description
limit number No Number of results per page (default: 50)
page number No Page number (default: 1)
shortcut string No Filter by shortcut text (case-insensitive partial match)

Example Request

curl "https://api.weellu.com/api/v1/profile/quick-message?limit=20&page=1&shortcut=hello" \
  -H "Authorization: Bearer YOUR_TOKEN"
const params = new URLSearchParams({
  limit: "20",
  page: "1",
  shortcut: "hello"
});
const response = await fetch(`https://api.weellu.com/api/v1/profile/quick-message?${params}`, {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  }
});
const data = await response.json();
final response = await chopperClient.get(
  Uri.parse('/api/v1/profile/quick-message?limit=20&page=1&shortcut=hello'),
  headers: {'Authorization': 'Bearer $token'},
);

Example Response

{
  "data": {
    "docs": [
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0d3",
        "userId": "64f1a2b3c4d5e6f7a8b9c0d1",
        "shortcut": "/hello",
        "desc": "Hello! How can I help you today?",
        "createdAt": "2026-03-18T10:00:00.000Z",
        "updatedAt": "2026-03-18T10:00:00.000Z"
      }
    ],
    "totalDocs": 1,
    "totalPages": 1,
    "page": 1,
    "hasNextPage": false
  }
}

Delete Quick Message

DELETE https://api.weellu.com/api/v1/profile/quick-message/:id

Deletes a specific quick message by its ID.

URL Parameters

Parameter Type Required Description
id string Yes MongoDB ObjectId of the quick message to delete

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/profile/quick-message/64f1a2b3c4d5e6f7a8b9c0d3" \
  -H "Authorization: Bearer YOUR_TOKEN"
const quickMsgId = "64f1a2b3c4d5e6f7a8b9c0d3";
const response = await fetch(`https://api.weellu.com/api/v1/profile/quick-message/${quickMsgId}`, {
  method: "DELETE",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  }
});
const data = await response.json();
final quickMsgId = '64f1a2b3c4d5e6f7a8b9c0d3';
final response = await chopperClient.delete(
  Uri.parse('/api/v1/profile/quick-message/$quickMsgId'),
  headers: {'Authorization': 'Bearer $token'},
);

Example Response

{
  "data": "Done"
}

Create Chat Export

POST https://api.weellu.com/api/v1/profile/exports

Creates a new chat export job. The export is processed asynchronously in a background queue. Rate limited to one export every 24 hours, and only one active export at a time.

Body Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room to export. You must be a member of this room.
dateFrom string No ISO 8601 date string for the start of the export range (e.g. "2026-01-01T00:00:00.000Z").
dateTo string No ISO 8601 date string for the end of the export range (e.g. "2026-03-18T23:59:59.000Z").
includeMedia boolean No Whether to include media attachments in the export (default: false).

Example Request

curl -X POST "https://api.weellu.com/api/v1/profile/exports" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "roomId": "64f1a2b3c4d5e6f7a8b9c0d4",
    "dateFrom": "2026-01-01T00:00:00.000Z",
    "dateTo": "2026-03-18T23:59:59.000Z",
    "includeMedia": false
  }'
const response = await fetch("https://api.weellu.com/api/v1/profile/exports", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    roomId: "64f1a2b3c4d5e6f7a8b9c0d4",
    dateFrom: "2026-01-01T00:00:00.000Z",
    dateTo: "2026-03-18T23:59:59.000Z",
    includeMedia: false
  })
});
const data = await response.json();
final response = await chopperClient.post(
  Uri.parse('/api/v1/profile/exports'),
  headers: {
    'Authorization': 'Bearer $token',
    'Content-Type': 'application/json',
  },
  body: jsonEncode({
    'roomId': '64f1a2b3c4d5e6f7a8b9c0d4',
    'dateFrom': '2026-01-01T00:00:00.000Z',
    'dateTo': '2026-03-18T23:59:59.000Z',
    'includeMedia': false,
  }),
);

Example Response

{
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d5",
    "userId": "64f1a2b3c4d5e6f7a8b9c0d1",
    "roomId": "64f1a2b3c4d5e6f7a8b9c0d4",
    "roomTitle": "Project Alpha",
    "dateFrom": "2026-01-01T00:00:00.000Z",
    "dateTo": "2026-03-18T23:59:59.000Z",
    "includeMedia": false,
    "status": "pending",
    "createdAt": "2026-03-18T15:00:00.000Z",
    "updatedAt": "2026-03-18T15:00:00.000Z"
  }
}

List Chat Exports

GET https://api.weellu.com/api/v1/profile/exports

Returns a paginated list of the authenticated user's chat exports, sorted by most recent first. Completed exports include a pre-signed download URL valid for 7 days.

Query Parameters

Parameter Type Required Description
limit number No Number of results per page (default: 20, must be > 0)
page number No Page number (default: 1, must be > 0)
lastId string No MongoDB ObjectId for cursor-based pagination

Example Request

curl "https://api.weellu.com/api/v1/profile/exports?limit=10&page=1" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch("https://api.weellu.com/api/v1/profile/exports?limit=10&page=1", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  }
});
const data = await response.json();
final response = await chopperClient.get(
  Uri.parse('/api/v1/profile/exports?limit=10&page=1'),
  headers: {'Authorization': 'Bearer $token'},
);

Example Response

{
  "data": {
    "docs": [
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0d5",
        "userId": "64f1a2b3c4d5e6f7a8b9c0d1",
        "roomId": "64f1a2b3c4d5e6f7a8b9c0d4",
        "roomTitle": "Project Alpha",
        "dateFrom": "2026-01-01T00:00:00.000Z",
        "dateTo": "2026-03-18T23:59:59.000Z",
        "includeMedia": false,
        "status": "completed",
        "filePath": "exports/64f1a2b3/chat-export-1710432000.json",
        "fileSize": 245678,
        "totalMessages": 1523,
        "completedAt": "2026-03-18T15:02:30.000Z",
        "expiresAt": "2026-03-25T15:02:30.000Z",
        "createdAt": "2026-03-18T15:00:00.000Z",
        "updatedAt": "2026-03-18T15:02:30.000Z",
        "downloadUrl": "https://s3.amazonaws.com/weellu/exports/64f1a2b3/chat-export-1710432000.json?X-Amz-Signature=..."
      }
    ],
    "totalDocs": 1,
    "totalPages": 1,
    "page": 1,
    "hasNextPage": false
  }
}

Get Chat Export by ID

GET https://api.weellu.com/api/v1/profile/exports/:exportId

Returns a single chat export by its ID. If the export is completed, includes a pre-signed download URL valid for 7 days.

URL Parameters

Parameter Type Required Description
exportId string Yes MongoDB ObjectId of the chat export

Example Request

curl "https://api.weellu.com/api/v1/profile/exports/64f1a2b3c4d5e6f7a8b9c0d5" \
  -H "Authorization: Bearer YOUR_TOKEN"
const exportId = "64f1a2b3c4d5e6f7a8b9c0d5";
const response = await fetch(`https://api.weellu.com/api/v1/profile/exports/${exportId}`, {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  }
});
const data = await response.json();
final exportId = '64f1a2b3c4d5e6f7a8b9c0d5';
final response = await chopperClient.get(
  Uri.parse('/api/v1/profile/exports/$exportId'),
  headers: {'Authorization': 'Bearer $token'},
);

Example Response

{
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d5",
    "userId": "64f1a2b3c4d5e6f7a8b9c0d1",
    "roomId": "64f1a2b3c4d5e6f7a8b9c0d4",
    "roomTitle": "Project Alpha",
    "dateFrom": "2026-01-01T00:00:00.000Z",
    "dateTo": "2026-03-18T23:59:59.000Z",
    "includeMedia": false,
    "status": "completed",
    "filePath": "exports/64f1a2b3/chat-export-1710432000.json",
    "fileSize": 245678,
    "totalMessages": 1523,
    "completedAt": "2026-03-18T15:02:30.000Z",
    "expiresAt": "2026-03-25T15:02:30.000Z",
    "createdAt": "2026-03-18T15:00:00.000Z",
    "updatedAt": "2026-03-18T15:02:30.000Z",
    "downloadUrl": "https://s3.amazonaws.com/weellu/exports/64f1a2b3/chat-export-1710432000.json?X-Amz-Signature=..."
  }
}

Business Profile

Business profile management endpoints. These allow users to create, update, and manage their business profiles on the Weellu platform. All endpoints require a valid Authorization: Bearer TOKEN header.

Enums Reference

BusinessStatus

Value Description
active Business profile is active and visible
notActive Business profile is deactivated/hidden
none User has no business profile

DaysEnum

Value Description
sunday Sunday
monday Monday
tuesday Tuesday
wednesday Wednesday
thursday Thursday
friday Friday
saturday Saturday

Data Models

OpeningHour Object

Field Type Required Description
day string Yes Day of the week. Must be one of DaysEnum values. Each day must be unique within the array.
open string No Opening time (e.g. "09:00"). Ignored if is24 is true.
close string No Closing time (e.g. "18:00"). Ignored if is24 is true.
is24 boolean Yes Whether the business is open 24 hours on this day.

BusinessProfile Object

Field Type Description
_id string MongoDB ObjectId
userId string Owner user's MongoDB ObjectId
businessName string Business display name
description string Business description text
logo string S3 key/URL of the business logo image
cover string S3 key/URL of the cover image (nullable)
images object[] Array of banner images, each with id (ObjectId) and value (S3 key)
location object GeoJSON Point with coordinates ([longitude, latitude]) and address (string)
openingHours object[] Array of OpeningHour objects
acceptCard boolean Whether the business accepts card payments
acceptPix boolean Whether the business accepts Pix payments
acceptCash boolean Whether the business accepts cash payments
status string One of BusinessStatus enum values
createdAt string ISO 8601 creation timestamp
updatedAt string ISO 8601 last update timestamp

Get My Business Profile

GET https://api.weellu.com/api/v1/profile/business/get

Returns the authenticated user's business profile, or null if no business profile exists.

Parameters

No parameters required.

Example Request

curl "https://api.weellu.com/api/v1/profile/business/get" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch("https://api.weellu.com/api/v1/profile/business/get", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  }
});
const data = await response.json();
final response = await chopperClient.get(
  Uri.parse('/api/v1/profile/business/get'),
  headers: {'Authorization': 'Bearer $token'},
);

Example Response

{
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0e1",
    "userId": "64f1a2b3c4d5e6f7a8b9c0d1",
    "businessName": "Cafe Primavera",
    "description": "Artisan coffee shop and bakery in downtown Sao Paulo",
    "logo": "https://cdn.weellu.com/business/64f1a2b3/logo.jpg",
    "cover": "https://cdn.weellu.com/business/64f1a2b3/cover.jpg",
    "images": [
      {
        "id": "64f1a2b3c4d5e6f7a8b9c100",
        "value": "https://cdn.weellu.com/business/64f1a2b3/banner1.jpg"
      },
      {
        "id": "64f1a2b3c4d5e6f7a8b9c101",
        "value": "https://cdn.weellu.com/business/64f1a2b3/banner2.jpg"
      }
    ],
    "location": {
      "type": "Point",
      "coordinates": [-46.6333, -23.5505],
      "address": "Rua Augusta, 1234, Sao Paulo, SP"
    },
    "openingHours": [
      {
        "day": "monday",
        "open": "08:00",
        "close": "22:00",
        "is24": false
      },
      {
        "day": "tuesday",
        "open": "08:00",
        "close": "22:00",
        "is24": false
      },
      {
        "day": "wednesday",
        "open": "08:00",
        "close": "22:00",
        "is24": false
      },
      {
        "day": "thursday",
        "open": "08:00",
        "close": "22:00",
        "is24": false
      },
      {
        "day": "friday",
        "open": "08:00",
        "close": "23:00",
        "is24": false
      },
      {
        "day": "saturday",
        "is24": true
      },
      {
        "day": "sunday",
        "open": "10:00",
        "close": "18:00",
        "is24": false
      }
    ],
    "acceptCard": true,
    "acceptPix": true,
    "acceptCash": true,
    "status": "active",
    "createdAt": "2026-01-15T10:30:00.000Z",
    "updatedAt": "2026-03-10T14:20:00.000Z"
  }
}

Get Peer Business Profile

GET https://api.weellu.com/api/v1/profile/:id/business

Returns another user's business profile, or null if they have no business profile.

URL Parameters

Parameter Type Required Description
id string Yes MongoDB ObjectId of the target user

Example Request

curl "https://api.weellu.com/api/v1/profile/64f1a2b3c4d5e6f7a8b9c0d1/business" \
  -H "Authorization: Bearer YOUR_TOKEN"
const userId = "64f1a2b3c4d5e6f7a8b9c0d1";
const response = await fetch(`https://api.weellu.com/api/v1/profile/${userId}/business`, {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  }
});
const data = await response.json();
final userId = '64f1a2b3c4d5e6f7a8b9c0d1';
final response = await chopperClient.get(
  Uri.parse('/api/v1/profile/$userId/business'),
  headers: {'Authorization': 'Bearer $token'},
);

Example Response

{
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0e1",
    "userId": "64f1a2b3c4d5e6f7a8b9c0d1",
    "businessName": "Cafe Primavera",
    "description": "Artisan coffee shop and bakery in downtown Sao Paulo",
    "logo": "https://cdn.weellu.com/business/64f1a2b3/logo.jpg",
    "cover": "https://cdn.weellu.com/business/64f1a2b3/cover.jpg",
    "images": [
      {
        "id": "64f1a2b3c4d5e6f7a8b9c100",
        "value": "https://cdn.weellu.com/business/64f1a2b3/banner1.jpg"
      }
    ],
    "location": {
      "type": "Point",
      "coordinates": [-46.6333, -23.5505],
      "address": "Rua Augusta, 1234, Sao Paulo, SP"
    },
    "openingHours": [
      {
        "day": "monday",
        "open": "08:00",
        "close": "22:00",
        "is24": false
      }
    ],
    "acceptCard": true,
    "acceptPix": true,
    "acceptCash": true,
    "status": "active",
    "createdAt": "2026-01-15T10:30:00.000Z",
    "updatedAt": "2026-03-10T14:20:00.000Z"
  }
}

Create Business Profile

POST https://api.weellu.com/api/v1/profile/business

Creates a new business profile for the authenticated user. Uses multipart/form-data encoding for file uploads. A user can only have one business profile. If a profile already exists (even if inactive), this endpoint returns an error -- use the activate endpoint instead.

File upload limits: each file max 40 MB, up to 20 banner images.

Body Parameters

Parameter Type Required Description
logo file Yes Business logo image file. Exactly one file required. Field name: logo.
cover file No Business cover image file. At most one file. Field name: cover.
file file[] No Banner images. Up to 20 files. Field name: file.
businessName string Yes Business display name.
address string Yes Business street address.
description string Yes Business description text.
longitude number Yes Longitude coordinate of the business location.
latitude number Yes Latitude coordinate of the business location.
acceptCard boolean Yes Whether the business accepts card payments.
acceptPix boolean Yes Whether the business accepts Pix payments.
acceptCash boolean Yes Whether the business accepts cash payments.
openingHours string (JSON) Yes JSON-encoded array of OpeningHour objects. Each day must be unique. See the OpeningHour object model above.

OpeningHour JSON Schema

Each element in the openingHours array:

Field Type Required Description
day string Yes One of: sunday, monday, tuesday, wednesday, thursday, friday, saturday. Must be unique.
open string No Opening time string (e.g. "09:00").
close string No Closing time string (e.g. "18:00").
is24 boolean Yes true if open 24 hours for this day.

Example Request

curl -X POST "https://api.weellu.com/api/v1/profile/business" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "logo=@/path/to/logo.png" \
  -F "cover=@/path/to/cover.jpg" \
  -F "file=@/path/to/banner1.jpg" \
  -F "file=@/path/to/banner2.jpg" \
  -F "businessName=Cafe Primavera" \
  -F "address=Rua Augusta, 1234, Sao Paulo, SP" \
  -F "description=Artisan coffee shop and bakery" \
  -F "longitude=-46.6333" \
  -F "latitude=-23.5505" \
  -F "acceptCard=true" \
  -F "acceptPix=true" \
  -F "acceptCash=true" \
  -F 'openingHours=[{"day":"monday","open":"08:00","close":"22:00","is24":false},{"day":"saturday","is24":true}]'
const formData = new FormData();
formData.append("logo", logoFile);
formData.append("cover", coverFile);
formData.append("file", bannerFile1);
formData.append("file", bannerFile2);
formData.append("businessName", "Cafe Primavera");
formData.append("address", "Rua Augusta, 1234, Sao Paulo, SP");
formData.append("description", "Artisan coffee shop and bakery");
formData.append("longitude", "-46.6333");
formData.append("latitude", "-23.5505");
formData.append("acceptCard", "true");
formData.append("acceptPix", "true");
formData.append("acceptCash", "true");
formData.append("openingHours", JSON.stringify([
  { day: "monday", open: "08:00", close: "22:00", is24: false },
  { day: "tuesday", open: "08:00", close: "22:00", is24: false },
  { day: "wednesday", open: "08:00", close: "22:00", is24: false },
  { day: "thursday", open: "08:00", close: "22:00", is24: false },
  { day: "friday", open: "08:00", close: "23:00", is24: false },
  { day: "saturday", is24: true },
  { day: "sunday", open: "10:00", close: "18:00", is24: false }
]));

const response = await fetch("https://api.weellu.com/api/v1/profile/business", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  },
  body: formData
});
const data = await response.json();
import 'package:http/http.dart' as http;
import 'dart:convert';

final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/profile/business'),
);
request.headers['Authorization'] = 'Bearer $token';

// Files
request.files.add(await http.MultipartFile.fromPath('logo', '/path/to/logo.png'));
request.files.add(await http.MultipartFile.fromPath('cover', '/path/to/cover.jpg'));
request.files.add(await http.MultipartFile.fromPath('file', '/path/to/banner1.jpg'));
request.files.add(await http.MultipartFile.fromPath('file', '/path/to/banner2.jpg'));

// Text fields
request.fields['businessName'] = 'Cafe Primavera';
request.fields['address'] = 'Rua Augusta, 1234, Sao Paulo, SP';
request.fields['description'] = 'Artisan coffee shop and bakery';
request.fields['longitude'] = '-46.6333';
request.fields['latitude'] = '-23.5505';
request.fields['acceptCard'] = 'true';
request.fields['acceptPix'] = 'true';
request.fields['acceptCash'] = 'true';
request.fields['openingHours'] = jsonEncode([
  {'day': 'monday', 'open': '08:00', 'close': '22:00', 'is24': false},
  {'day': 'saturday', 'is24': true},
]);

final response = await request.send();

Example Response

{
  "data": "User profile created successfully"
}

Update Business Profile

PATCH https://api.weellu.com/api/v1/profile/business

Updates an existing business profile. Uses multipart/form-data encoding. All fields are optional -- only provided fields are updated. New banner images are appended to the existing list. To remove banners, use the deletedBanners field.

File upload limits: each file max 40 MB, up to 20 banner images per request.

Body Parameters

Parameter Type Required Description
logo file No New business logo image. Field name: logo.
cover file No New business cover image. Field name: cover.
file file[] No Additional banner images to append. Up to 20 files. Field name: file.
businessName string No Updated business display name.
address string No Updated business street address.
description string No Updated business description text.
longitude number No Updated longitude coordinate.
latitude number No Updated latitude coordinate.
acceptCard boolean No Whether the business accepts card payments.
acceptPix boolean No Whether the business accepts Pix payments.
acceptCash boolean No Whether the business accepts cash payments.
openingHours string (JSON) No JSON-encoded array of OpeningHour objects. Replaces all existing opening hours. Each day must be unique.
deletedBanners string No Comma-separated list of banner ObjectIds to remove, or a JSON array string (e.g. "id1,id2" or "[id1,id2]").

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/profile/business" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "businessName=Cafe Primavera - Pinheiros" \
  -F "description=Artisan coffee shop, bakery, and brunch spot" \
  -F "acceptCard=true" \
  -F "file=@/path/to/new-banner.jpg" \
  -F "deletedBanners=64f1a2b3c4d5e6f7a8b9c100"
const formData = new FormData();
formData.append("businessName", "Cafe Primavera - Pinheiros");
formData.append("description", "Artisan coffee shop, bakery, and brunch spot");
formData.append("acceptCard", "true");
formData.append("file", newBannerFile);
formData.append("deletedBanners", "64f1a2b3c4d5e6f7a8b9c100");

const response = await fetch("https://api.weellu.com/api/v1/profile/business", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  },
  body: formData
});
const data = await response.json();
import 'package:http/http.dart' as http;

final request = http.MultipartRequest(
  'PATCH',
  Uri.parse('https://api.weellu.com/api/v1/profile/business'),
);
request.headers['Authorization'] = 'Bearer $token';

request.fields['businessName'] = 'Cafe Primavera - Pinheiros';
request.fields['description'] = 'Artisan coffee shop, bakery, and brunch spot';
request.fields['acceptCard'] = 'true';
request.fields['deletedBanners'] = '64f1a2b3c4d5e6f7a8b9c100';
request.files.add(await http.MultipartFile.fromPath('file', '/path/to/new-banner.jpg'));

final response = await request.send();

Example Response

{
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0e1",
    "userId": "64f1a2b3c4d5e6f7a8b9c0d1",
    "businessName": "Cafe Primavera - Pinheiros",
    "description": "Artisan coffee shop, bakery, and brunch spot",
    "logo": "https://cdn.weellu.com/business/64f1a2b3/logo.jpg",
    "cover": "https://cdn.weellu.com/business/64f1a2b3/cover.jpg",
    "images": [
      {
        "id": "64f1a2b3c4d5e6f7a8b9c101",
        "value": "https://cdn.weellu.com/business/64f1a2b3/banner2.jpg"
      },
      {
        "id": "64f1a2b3c4d5e6f7a8b9c102",
        "value": "https://cdn.weellu.com/business/64f1a2b3/new-banner.jpg"
      }
    ],
    "location": {
      "type": "Point",
      "coordinates": [-46.6333, -23.5505],
      "address": "Rua Augusta, 1234, Sao Paulo, SP"
    },
    "openingHours": [
      {
        "day": "monday",
        "open": "08:00",
        "close": "22:00",
        "is24": false
      },
      {
        "day": "saturday",
        "is24": true
      }
    ],
    "acceptCard": true,
    "acceptPix": true,
    "acceptCash": true,
    "status": "active",
    "createdAt": "2026-01-15T10:30:00.000Z",
    "updatedAt": "2026-03-18T16:00:00.000Z"
  }
}

Deactivate Business Profile

PATCH https://api.weellu.com/api/v1/profile/business/inactivate

Deactivates the authenticated user's business profile. Sets the business status to notActive. The business profile data is preserved and can be reactivated later.

Parameters

No parameters required.

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/profile/business/inactivate" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch("https://api.weellu.com/api/v1/profile/business/inactivate", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  }
});
const data = await response.json();
final response = await chopperClient.patch(
  Uri.parse('/api/v1/profile/business/inactivate'),
  headers: {'Authorization': 'Bearer $token'},
);

Example Response

{
  "data": "User profile inactive successfully"
}

Activate Business Profile

PATCH https://api.weellu.com/api/v1/profile/business/active

Reactivates the authenticated user's business profile. Sets the business status to active. The business profile must already exist (created via POST /profile/business).

Parameters

No parameters required.

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/profile/business/active" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch("https://api.weellu.com/api/v1/profile/business/active", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN"
  }
});
const data = await response.json();
final response = await chopperClient.patch(
  Uri.parse('/api/v1/profile/business/active'),
  headers: {'Authorization': 'Bearer $token'},
);

Example Response

{
  "data": "User profile active successfully"
}

Channels

All channel endpoints require authentication via Bearer token.

Authorization: Bearer TOKEN

All responses are wrapped in:

{
  "code": 2000,
  "data": { ... },
  "msg": null
}

Enums Reference

RoomType

Value Description
s Single (1-to-1 direct message)
g Group chat
b Broadcast channel
p Project room
c Channel
sy System

GroupRoleType

Value Description
member Regular member
superAdmin Super administrator (creator)
admin Administrator
broadcaster Broadcaster (can send messages but limited admin rights)

BroadcastRoleType

Value Description
member Regular member
superAdmin Super administrator (creator)
admin Administrator

Get Rooms List

GET https://api.weellu.com/api/v1/channel/v2

Returns a paginated list of rooms (channels) for the authenticated user. Supports filtering by room type and searching by title.

Query Parameters

Parameter Type Required Description
roomType string No Filter by room type: s, g, b, p
page number No Page number (default: 1)
limit number No Items per page (default: 20)
title string No Search rooms by title (partial match)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/v2?roomType=g&page=1&limit=20" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/v2?roomType=g&page=1&limit=20",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/v2',
  parameters: {'roomType': 'g', 'page': '1', 'limit': '20'},
);

Example Response

{
  "code": 2000,
  "data": {
    "docs": [
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
        "uId": "64a1b2c3d4e5f6a7b8c9d0e1",
        "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "rT": "g",
        "t": "Engineering Team",
        "tEn": "Engineering Team",
        "nTitle": null,
        "img": "https://s3.amazonaws.com/weellu/group-img.jpg",
        "isD": false,
        "isA": false,
        "isM": false,
        "isPin": false,
        "tTo": null,
        "chatWallpaper": null,
        "lastMsgId": "64f1a2b3c4d5e6f7a8b9c0d3",
        "uC": 5,
        "mentionsCount": 1,
        "lastMessage": {
          "_id": "64f1a2b3c4d5e6f7a8b9c0d3",
          "msg": "Hello everyone!",
          "mT": "text",
          "sId": "64a1b2c3d4e5f6a7b8c9d0e2",
          "createdAt": "2026-03-18T10:30:00.000Z"
        },
        "createdAt": "2026-03-01T08:00:00.000Z"
      }
    ],
    "totalDocs": 45,
    "limit": 20,
    "page": 1,
    "totalPages": 3,
    "hasNextPage": true,
    "hasPrevPage": false
  },
  "msg": null
}

Get Unread Room Counter

GET https://api.weellu.com/api/v1/channel/unread-room-counter

Returns the total unread message count across all rooms for the authenticated user.

Parameters

No parameters required.

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/unread-room-counter" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/unread-room-counter",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get('/channel/unread-room-counter');

Example Response

{
  "code": 2000,
  "data": [
    {
      "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
      "uC": 5,
      "mentionsCount": 1
    },
    {
      "rId": "64f1a2b3c4d5e6f7a8b9c0d9",
      "uC": 12,
      "mentionsCount": 0
    }
  ],
  "msg": null
}

Get or Create Peer Room

GET https://api.weellu.com/api/v1/channel/get-peer-room/:peerId

Gets an existing single (1-to-1) chat room with the specified peer, or creates one if it does not exist.

Path Parameters

Parameter Type Required Description
peerId string Yes MongoDB ObjectId of the peer user

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/get-peer-room/64a1b2c3d4e5f6a7b8c9d0e2" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/get-peer-room/64a1b2c3d4e5f6a7b8c9d0e2",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/get-peer-room/64a1b2c3d4e5f6a7b8c9d0e2',
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "uId": "64a1b2c3d4e5f6a7b8c9d0e1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "rT": "s",
    "t": "John Doe",
    "tEn": "John Doe",
    "nTitle": null,
    "img": "https://s3.amazonaws.com/weellu/user-avatar.jpg",
    "isD": false,
    "isA": false,
    "isM": false,
    "isPin": false,
    "pId": "64a1b2c3d4e5f6a7b8c9d0e2",
    "bId": null,
    "tTo": null,
    "chatWallpaper": null,
    "lastMsgId": null,
    "uC": 0,
    "mentionsCount": 0,
    "createdAt": "2026-03-18T10:30:00.000Z"
  },
  "msg": null
}

Get Room by ID

GET https://api.weellu.com/api/v1/channel/:roomId

Returns full details of a specific room by its ID.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get('/channel/64f1a2b3c4d5e6f7a8b9c0d2');

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "uId": "64a1b2c3d4e5f6a7b8c9d0e1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "rT": "g",
    "t": "Engineering Team",
    "tEn": "Engineering Team",
    "nTitle": null,
    "img": "https://s3.amazonaws.com/weellu/group-img.jpg",
    "isD": false,
    "isA": false,
    "isM": false,
    "isPin": false,
    "tTo": null,
    "chatWallpaper": null,
    "lastMsgId": "64f1a2b3c4d5e6f7a8b9c0d3",
    "uC": 3,
    "mentionsCount": 0,
    "lastMessage": {
      "_id": "64f1a2b3c4d5e6f7a8b9c0d3",
      "msg": "Let's sync up tomorrow",
      "mT": "text",
      "sId": "64a1b2c3d4e5f6a7b8c9d0e2",
      "createdAt": "2026-03-18T09:15:00.000Z"
    },
    "createdAt": "2026-03-01T08:00:00.000Z"
  },
  "msg": null
}

Get Room Unread Count

GET https://api.weellu.com/api/v1/channel/:roomId/un-read-count

Returns the unread message count for a specific room.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/un-read-count" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/un-read-count",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/un-read-count',
);

Example Response

{
  "code": 2000,
  "data": {
    "count": 7
  },
  "msg": null
}

Archive Room

PATCH https://api.weellu.com/api/v1/channel/:roomId/archive

Archives a room for the authenticated user. Archived rooms are hidden from the main room list.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/archive" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/archive",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/archive',
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "isA": true
  },
  "msg": null
}

Unarchive Room

PATCH https://api.weellu.com/api/v1/channel/:roomId/un-archive

Unarchives a previously archived room, restoring it to the main room list.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/un-archive" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/un-archive",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/un-archive',
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "isA": false
  },
  "msg": null
}

Pin Room

PATCH https://api.weellu.com/api/v1/channel/:roomId/pin

Pins a room to the top of the room list.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/pin" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/pin",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/pin',
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "isPin": true
  },
  "msg": null
}

Unpin Room

PATCH https://api.weellu.com/api/v1/channel/:roomId/unpin

Unpins a room from the top of the room list.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/unpin" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/unpin",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/unpin',
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "isPin": false
  },
  "msg": null
}

Toggle Notifications

PATCH https://api.weellu.com/api/v1/channel/:roomId/notification

Toggles push notifications on or off for a specific room. If currently enabled, it disables them and vice versa.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/notification" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/notification",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/notification',
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "isM": true
  },
  "msg": null
}

Mute Room Notifications

PATCH https://api.weellu.com/api/v1/channel/:roomId/notification/mute

Mutes notifications for a specific room. The user will not receive push notifications for new messages in this room.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/notification/mute" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/notification/mute",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/notification/mute',
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "isM": true
  },
  "msg": null
}

Unmute Room Notifications

PATCH https://api.weellu.com/api/v1/channel/:roomId/notification/un-mute

Unmutes notifications for a specific room, re-enabling push notifications.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/notification/un-mute" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/notification/un-mute",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/notification/un-mute',
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "isM": false
  },
  "msg": null
}

Set Nickname

PATCH https://api.weellu.com/api/v1/channel/:roomId/nick-name

Sets a custom nickname/display name for a room. This overrides the default room title for the authenticated user only.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Body Parameters

Parameter Type Required Description
name string Yes The custom nickname to set for the room

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/nick-name" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "My Dev Team"}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/nick-name",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ name: "My Dev Team" })
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/nick-name',
  body: {'name': 'My Dev Team'},
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "nTitle": "My Dev Team"
  },
  "msg": null
}

Set Wallpaper URL

PATCH https://api.weellu.com/api/v1/channel/:roomId/wallpaper

Sets a chat wallpaper for the room using a URL string.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Body Parameters

Parameter Type Required Description
chatWallpaper string No URL of the wallpaper image. Pass null to remove.

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/wallpaper" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"chatWallpaper": "https://s3.amazonaws.com/weellu/wallpapers/blue-gradient.jpg"}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/wallpaper",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      chatWallpaper: "https://s3.amazonaws.com/weellu/wallpapers/blue-gradient.jpg"
    })
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/wallpaper',
  body: {'chatWallpaper': 'https://s3.amazonaws.com/weellu/wallpapers/blue-gradient.jpg'},
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "chatWallpaper": "https://s3.amazonaws.com/weellu/wallpapers/blue-gradient.jpg"
  },
  "msg": null
}

Upload Wallpaper

POST https://api.weellu.com/api/v1/channel/:roomId/wallpaper

Uploads an image file to be used as the chat wallpaper. The server stores it on S3 and sets the wallpaper URL automatically.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Body Parameters (multipart/form-data)

Parameter Type Required Description
file file Yes Image file to upload (JPEG, PNG, etc.)

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/wallpaper" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "file=@/path/to/wallpaper.jpg"
const formData = new FormData();
formData.append("file", fileInput.files[0]);

const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/wallpaper",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    },
    body: formData
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/wallpaper'),
);
request.headers['Authorization'] = 'Bearer YOUR_TOKEN';
request.files.add(await http.MultipartFile.fromPath('file', filePath));
final response = await request.send();

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "chatWallpaper": "https://s3.amazonaws.com/weellu/wallpapers/uploaded-64f1a2b3.jpg"
  },
  "msg": null
}

Enable Translation

PATCH https://api.weellu.com/api/v1/channel/:roomId/translate

Enables automatic message translation for the room. All incoming messages will be translated to the specified language.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Body Parameters

Parameter Type Required Description
transTo string Yes Target language code (e.g., en, es, pt, ar, fr, de)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/translate" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"transTo": "en"}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/translate",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ transTo: "en" })
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/translate',
  body: {'transTo': 'en'},
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "tTo": "en"
  },
  "msg": null
}

Stop Translation

PATCH https://api.weellu.com/api/v1/channel/:roomId/translate/stop

Disables automatic message translation for the room.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/translate/stop" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/translate/stop",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/translate/stop',
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "tTo": null
  },
  "msg": null
}

Mark as Delivered

PATCH https://api.weellu.com/api/v1/channel/:roomId/deliver

Marks all messages in the room as delivered for the authenticated user. This updates the delivery status for all undelivered messages.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/deliver" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/deliver",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/deliver',
);

Example Response

{
  "code": 2000,
  "data": null,
  "msg": null
}

URL Preview

GET https://api.weellu.com/api/v1/channel/:roomId/url-preview

Fetches Open Graph metadata for a URL to generate a link preview (title, description, image).

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Query Parameters

Parameter Type Required Description
url string Yes The URL to fetch preview data for

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/url-preview?url=https://example.com/article" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/url-preview?url=https://example.com/article",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/url-preview',
  parameters: {'url': 'https://example.com/article'},
);

Example Response

{
  "code": 2000,
  "data": {
    "title": "Example Article Title",
    "description": "A brief description of the article content.",
    "image": "https://example.com/og-image.jpg",
    "url": "https://example.com/article",
    "siteName": "Example.com"
  },
  "msg": null
}

Get Assist Task

GET https://api.weellu.com/api/v1/channel/:roomId/assist

Returns the assist task associated with a room, if any. Used for AI assistant integration within chat rooms.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/assist" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/assist",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/assist',
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d5",
    "roomId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "assistId": "64a1b2c3d4e5f6a7b8c9d0e5",
    "status": "open",
    "createdAt": "2026-03-18T10:00:00.000Z"
  },
  "msg": null
}

My Single Chat Info

GET https://api.weellu.com/api/v1/channel/:roomId/single/my-info

Returns the authenticated user's room member record for a single (1-to-1) chat room.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the single chat room

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/single/my-info" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/single/my-info",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/single/my-info',
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "uId": "64a1b2c3d4e5f6a7b8c9d0e1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "rT": "s",
    "t": "John Doe",
    "tEn": "John Doe",
    "nTitle": null,
    "img": "https://s3.amazonaws.com/weellu/user-avatar.jpg",
    "isD": false,
    "isA": false,
    "isM": false,
    "isPin": false,
    "pId": "64a1b2c3d4e5f6a7b8c9d0e2",
    "bId": null,
    "tTo": null,
    "chatWallpaper": null,
    "uC": 0,
    "mentionsCount": 0,
    "createdAt": "2026-03-01T08:00:00.000Z"
  },
  "msg": null
}

Peer Single Chat Info

GET https://api.weellu.com/api/v1/channel/:roomId/single/info

Returns the peer user's information for a single (1-to-1) chat room, including their profile data.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the single chat room

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/single/info" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/single/info",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/single/info',
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64a1b2c3d4e5f6a7b8c9d0e2",
    "fullName": "John Doe",
    "img": "https://s3.amazonaws.com/weellu/user-avatar.jpg",
    "bio": "Software Engineer",
    "lastSeenAt": "2026-03-18T10:25:00.000Z",
    "isOnline": true
  },
  "msg": null
}

Delete Room

DELETE https://api.weellu.com/api/v1/channel/:roomId

Soft-deletes a room for the authenticated user. The room is marked as deleted and hidden from the room list.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2",
  {
    method: "DELETE",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2',
);

Example Response

{
  "code": 2000,
  "data": null,
  "msg": null
}

Clear All Messages

DELETE https://api.weellu.com/api/v1/channel/:roomId/messages/all

Clears all messages in the room for the authenticated user. Other members' message history is not affected.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/messages/all" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/messages/all",
  {
    method: "DELETE",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/messages/all',
);

Example Response

{
  "code": 2000,
  "data": null,
  "msg": null
}

Get All Starred Messages

GET https://api.weellu.com/api/v1/channel/messages/stars

Returns all messages that the authenticated user has starred across all rooms. Supports pagination.

Query Parameters

Parameter Type Required Description
page number No Page number (default: 1)
limit number No Items per page (default: 20)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/messages/stars?page=1&limit=20" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/messages/stars?page=1&limit=20",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/messages/stars',
  parameters: {'page': '1', 'limit': '20'},
);

Example Response

{
  "code": 2000,
  "data": {
    "docs": [
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0d3",
        "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "msg": "Important message to remember",
        "mT": "text",
        "sId": "64a1b2c3d4e5f6a7b8c9d0e2",
        "senderName": "John Doe",
        "senderImg": "https://s3.amazonaws.com/weellu/user-avatar.jpg",
        "createdAt": "2026-03-15T14:20:00.000Z"
      },
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0d7",
        "rId": "64f1a2b3c4d5e6f7a8b9c0d9",
        "msg": "Meeting link: https://meet.example.com/abc",
        "mT": "text",
        "sId": "64a1b2c3d4e5f6a7b8c9d0e3",
        "senderName": "Jane Smith",
        "senderImg": "https://s3.amazonaws.com/weellu/user-avatar2.jpg",
        "createdAt": "2026-03-10T09:00:00.000Z"
      }
    ],
    "totalDocs": 12,
    "limit": 20,
    "page": 1,
    "totalPages": 1,
    "hasNextPage": false,
    "hasPrevPage": false
  },
  "msg": null
}

Group Chats

Group chat endpoints allow you to create and manage group conversations. All endpoints require authentication via Bearer token.

Authorization: Bearer TOKEN

Create Group

POST https://api.weellu.com/api/v1/channel/group

Creates a new group chat room. Supports an optional group image upload via multipart form data.

Body Parameters (multipart/form-data)

Parameter Type Required Description
groupName string Yes Name of the group
peerIds string (JSON array) Yes JSON-encoded array of MongoDB ObjectIds of users to add
file file No Optional group image (JPEG, PNG, etc.)

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/group" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F 'groupName=Engineering Team' \
  -F 'peerIds=["64a1b2c3d4e5f6a7b8c9d0e2","64a1b2c3d4e5f6a7b8c9d0e3"]' \
  -F "file=@/path/to/group-image.jpg"
const formData = new FormData();
formData.append("groupName", "Engineering Team");
formData.append("peerIds", JSON.stringify([
  "64a1b2c3d4e5f6a7b8c9d0e2",
  "64a1b2c3d4e5f6a7b8c9d0e3"
]));
formData.append("file", imageFile);

const response = await fetch(
  "https://api.weellu.com/api/v1/channel/group",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    },
    body: formData
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/channel/group'),
);
request.headers['Authorization'] = 'Bearer YOUR_TOKEN';
request.fields['groupName'] = 'Engineering Team';
request.fields['peerIds'] = jsonEncode([
  '64a1b2c3d4e5f6a7b8c9d0e2',
  '64a1b2c3d4e5f6a7b8c9d0e3',
]);
request.files.add(await http.MultipartFile.fromPath('file', imagePath));
final response = await request.send();

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "uId": "64a1b2c3d4e5f6a7b8c9d0e1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "rT": "g",
    "t": "Engineering Team",
    "tEn": "Engineering Team",
    "nTitle": null,
    "img": "https://s3.amazonaws.com/weellu/groups/64f1a2b3.jpg",
    "isD": false,
    "isA": false,
    "isM": false,
    "isPin": false,
    "tTo": null,
    "chatWallpaper": null,
    "lastMsgId": null,
    "uC": 0,
    "mentionsCount": 0,
    "createdAt": "2026-03-18T12:00:00.000Z"
  },
  "msg": null
}

Get Group Info

GET https://api.weellu.com/api/v1/channel/:roomId/group/info

Returns the group settings and metadata (name, image, description, creator, pinned message).

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the group room

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/info" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/info",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/info',
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d2",
    "cId": "64a1b2c3d4e5f6a7b8c9d0e1",
    "gName": "Engineering Team",
    "gImg": "https://s3.amazonaws.com/weellu/groups/64f1a2b3.jpg",
    "desc": "Team discussions and standups",
    "pinMsg": null,
    "customMsg": null
  },
  "msg": null
}

Get My Group Info

GET https://api.weellu.com/api/v1/channel/:roomId/group/my-info

Returns the authenticated user's room member record for the group, including their role, mute status, archive status, and other personal settings.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the group room

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/my-info" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/my-info",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/my-info',
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "uId": "64a1b2c3d4e5f6a7b8c9d0e1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "rT": "g",
    "t": "Engineering Team",
    "tEn": "Engineering Team",
    "nTitle": null,
    "img": "https://s3.amazonaws.com/weellu/groups/64f1a2b3.jpg",
    "isD": false,
    "isA": false,
    "isM": false,
    "isPin": false,
    "tTo": null,
    "chatWallpaper": null,
    "uC": 3,
    "mentionsCount": 1,
    "createdAt": "2026-03-01T08:00:00.000Z"
  },
  "msg": null
}

List Group Members

GET https://api.weellu.com/api/v1/channel/:roomId/group/members

Returns a paginated list of group members. Supports searching by full name and cursor-based pagination.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the group room

Query Parameters

Parameter Type Required Description
page number No Page number (default: 1)
limit number No Items per page (default: 20)
lastId string No Last member ID for cursor-based pagination
fullName string No Search members by full name (partial match)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/members?page=1&limit=20" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/members?page=1&limit=20",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/members',
  parameters: {'page': '1', 'limit': '20'},
);

Example Response

{
  "code": 2000,
  "data": {
    "docs": [
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0a1",
        "uId": "64a1b2c3d4e5f6a7b8c9d0e1",
        "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "gR": "superAdmin",
        "userData": {
          "_id": "64a1b2c3d4e5f6a7b8c9d0e1",
          "fullName": "Alice Johnson",
          "img": "https://s3.amazonaws.com/weellu/avatars/alice.jpg",
          "bio": "Product Manager"
        },
        "createdAt": "2026-03-01T08:00:00.000Z"
      },
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0a2",
        "uId": "64a1b2c3d4e5f6a7b8c9d0e2",
        "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "gR": "admin",
        "userData": {
          "_id": "64a1b2c3d4e5f6a7b8c9d0e2",
          "fullName": "Bob Williams",
          "img": "https://s3.amazonaws.com/weellu/avatars/bob.jpg",
          "bio": "Senior Developer"
        },
        "createdAt": "2026-03-01T08:05:00.000Z"
      },
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0a3",
        "uId": "64a1b2c3d4e5f6a7b8c9d0e3",
        "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "gR": "member",
        "userData": {
          "_id": "64a1b2c3d4e5f6a7b8c9d0e3",
          "fullName": "Carol Davis",
          "img": "https://s3.amazonaws.com/weellu/avatars/carol.jpg",
          "bio": "Designer"
        },
        "createdAt": "2026-03-02T10:00:00.000Z"
      }
    ],
    "totalDocs": 15,
    "limit": 20,
    "page": 1,
    "totalPages": 1,
    "hasNextPage": false,
    "hasPrevPage": false
  },
  "msg": null
}

List Group Members V2

GET https://api.weellu.com/api/v1/channel/:roomId/group/members/v2

Returns group members using the v2 endpoint with enhanced query capabilities.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the group room

Query Parameters

Parameter Type Required Description
page number No Page number (default: 1)
limit number No Items per page (default: 20)
fullName string No Search members by full name

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/members/v2?page=1&limit=10" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/members/v2?page=1&limit=10",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/members/v2',
  parameters: {'page': '1', 'limit': '10'},
);

Example Response

{
  "code": 2000,
  "data": {
    "docs": [
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0a1",
        "uId": "64a1b2c3d4e5f6a7b8c9d0e1",
        "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "gR": "superAdmin",
        "userData": {
          "_id": "64a1b2c3d4e5f6a7b8c9d0e1",
          "fullName": "Alice Johnson",
          "img": "https://s3.amazonaws.com/weellu/avatars/alice.jpg",
          "bio": "Product Manager"
        },
        "createdAt": "2026-03-01T08:00:00.000Z"
      }
    ],
    "totalDocs": 15,
    "limit": 10,
    "page": 1,
    "totalPages": 2,
    "hasNextPage": true,
    "hasPrevPage": false
  },
  "msg": null
}

Add Members to Group

POST https://api.weellu.com/api/v1/channel/:roomId/group/members

Adds one or more members to an existing group chat.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the group room

Body Parameters

Parameter Type Required Description
ids array Yes Array of MongoDB ObjectIds of users to add

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/members" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"ids": ["64a1b2c3d4e5f6a7b8c9d0e4", "64a1b2c3d4e5f6a7b8c9d0e5"]}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/members",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      ids: ["64a1b2c3d4e5f6a7b8c9d0e4", "64a1b2c3d4e5f6a7b8c9d0e5"]
    })
  }
);
const data = await response.json();
final response = await chopper.post(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/members',
  body: {
    'ids': ['64a1b2c3d4e5f6a7b8c9d0e4', '64a1b2c3d4e5f6a7b8c9d0e5'],
  },
);

Example Response

{
  "code": 2000,
  "data": null,
  "msg": null
}

Kick Group Member

DELETE https://api.weellu.com/api/v1/channel/:roomId/group/members/:peerId

Removes a member from the group. Only admins and super admins can kick members.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the group room
peerId string Yes MongoDB ObjectId of the user to remove

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/members/64a1b2c3d4e5f6a7b8c9d0e3" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/members/64a1b2c3d4e5f6a7b8c9d0e3",
  {
    method: "DELETE",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/members/64a1b2c3d4e5f6a7b8c9d0e3',
);

Example Response

{
  "code": 2000,
  "data": null,
  "msg": null
}

Update Member Role

PATCH https://api.weellu.com/api/v1/channel/:roomId/group/members/:peerId/:role

Updates the role of a group member. Only super admins can change member roles.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the group room
peerId string Yes MongoDB ObjectId of the user whose role is being changed
role string Yes New role. One of: member, superAdmin, admin, broadcaster

GroupRoleType Enum

Value Description
member Regular group member, can send and read messages
superAdmin Group creator with full control
admin Administrator with member management permissions
broadcaster Can send messages but has limited admin rights

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/members/64a1b2c3d4e5f6a7b8c9d0e3/admin" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/members/64a1b2c3d4e5f6a7b8c9d0e3/admin",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/members/64a1b2c3d4e5f6a7b8c9d0e3/admin',
);

Example Response

{
  "code": 2000,
  "data": null,
  "msg": null
}

Transfer Super Admin

PATCH https://api.weellu.com/api/v1/channel/:roomId/group/transfer-super-admin/:peerId

Transfers super admin ownership of the group to another member. The current super admin is demoted to admin.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the group room
peerId string Yes MongoDB ObjectId of the user to become the new super admin

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/transfer-super-admin/64a1b2c3d4e5f6a7b8c9d0e2" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/transfer-super-admin/64a1b2c3d4e5f6a7b8c9d0e2",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/transfer-super-admin/64a1b2c3d4e5f6a7b8c9d0e2',
);

Example Response

{
  "code": 2000,
  "data": null,
  "msg": null
}

Leave Group

POST https://api.weellu.com/api/v1/channel/:roomId/group/leave

The authenticated user leaves the group. If the user is the super admin, they must transfer ownership first.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the group room

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/leave" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/leave",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.post(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/leave',
);

Example Response

{
  "code": 2000,
  "data": null,
  "msg": null
}

Delete Group

DELETE https://api.weellu.com/api/v1/channel/:roomId/group/destroy

Permanently destroys a group chat. Only the super admin can perform this action. All messages and member data are deleted.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the group room

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/destroy" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/destroy",
  {
    method: "DELETE",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/destroy',
);

Example Response

{
  "code": 2000,
  "data": null,
  "msg": null
}

Update Group Title

PATCH https://api.weellu.com/api/v1/channel/:roomId/group/title

Updates the display title/name of the group. Only admins and super admins can update the title.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the group room

Body Parameters

Parameter Type Required Description
title string Yes The new group title

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/title" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Backend Engineering"}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/title",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ title: "Backend Engineering" })
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/title',
  body: {'title': 'Backend Engineering'},
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d2",
    "gName": "Backend Engineering"
  },
  "msg": null
}

Update Group Image

PATCH https://api.weellu.com/api/v1/channel/:roomId/group/image

Updates the group avatar image. Only admins and super admins can update the image.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the group room

Body Parameters (multipart/form-data)

Parameter Type Required Description
file file Yes Image file to upload (JPEG, PNG, etc.)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/image" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "file=@/path/to/new-group-image.jpg"
const formData = new FormData();
formData.append("file", imageFile);

const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/image",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    },
    body: formData
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'PATCH',
  Uri.parse('https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/image'),
);
request.headers['Authorization'] = 'Bearer YOUR_TOKEN';
request.files.add(await http.MultipartFile.fromPath('file', imagePath));
final response = await request.send();

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d2",
    "gImg": "https://s3.amazonaws.com/weellu/groups/64f1a2b3-new.jpg"
  },
  "msg": null
}

Get Group Message Status

GET https://api.weellu.com/api/v1/channel/:roomId/group/message/:messageId/status/:type

Returns the delivery or seen status of a specific message for all group members. Useful for showing "read by" or "delivered to" lists.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the group room
messageId string Yes MongoDB ObjectId of the message
type string Yes Status type: seen or deliver

Query Parameters

Parameter Type Required Description
page number No Page number (default: 1)
limit number No Items per page (default: 20)

MessageStatusType Enum

Value Description
seen Members who have read the message
deliver Members who have received (but not necessarily read) the message

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/message/64f1a2b3c4d5e6f7a8b9c0d3/status/seen?page=1&limit=20" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/message/64f1a2b3c4d5e6f7a8b9c0d3/status/seen?page=1&limit=20",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/group/message/64f1a2b3c4d5e6f7a8b9c0d3/status/seen',
  parameters: {'page': '1', 'limit': '20'},
);

Example Response

{
  "code": 2000,
  "data": {
    "docs": [
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0b1",
        "uId": "64a1b2c3d4e5f6a7b8c9d0e2",
        "userData": {
          "_id": "64a1b2c3d4e5f6a7b8c9d0e2",
          "fullName": "Bob Williams",
          "img": "https://s3.amazonaws.com/weellu/avatars/bob.jpg"
        },
        "date": "2026-03-18T10:32:00.000Z"
      },
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0b2",
        "uId": "64a1b2c3d4e5f6a7b8c9d0e3",
        "userData": {
          "_id": "64a1b2c3d4e5f6a7b8c9d0e3",
          "fullName": "Carol Davis",
          "img": "https://s3.amazonaws.com/weellu/avatars/carol.jpg"
        },
        "date": "2026-03-18T10:35:00.000Z"
      }
    ],
    "totalDocs": 10,
    "limit": 20,
    "page": 1,
    "totalPages": 1,
    "hasNextPage": false,
    "hasPrevPage": false
  },
  "msg": null
}

Broadcasts

Broadcast channel endpoints allow you to create and manage one-to-many messaging channels. Only admins and super admins can send messages in broadcasts. All endpoints require authentication via Bearer token.

Authorization: Bearer TOKEN

Create Broadcast

POST https://api.weellu.com/api/v1/channel/broadcast

Creates a new broadcast channel. Supports an optional image upload via multipart form data.

Body Parameters (multipart/form-data)

Parameter Type Required Description
broadcastName string Yes Name of the broadcast channel
peerIds string (JSON array) Yes JSON-encoded array of MongoDB ObjectIds of users to add
file file No Optional broadcast image (JPEG, PNG, etc.)

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/broadcast" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F 'broadcastName=Company Announcements' \
  -F 'peerIds=["64a1b2c3d4e5f6a7b8c9d0e2","64a1b2c3d4e5f6a7b8c9d0e3","64a1b2c3d4e5f6a7b8c9d0e4"]' \
  -F "file=@/path/to/broadcast-image.jpg"
const formData = new FormData();
formData.append("broadcastName", "Company Announcements");
formData.append("peerIds", JSON.stringify([
  "64a1b2c3d4e5f6a7b8c9d0e2",
  "64a1b2c3d4e5f6a7b8c9d0e3",
  "64a1b2c3d4e5f6a7b8c9d0e4"
]));
formData.append("file", imageFile);

const response = await fetch(
  "https://api.weellu.com/api/v1/channel/broadcast",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    },
    body: formData
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/channel/broadcast'),
);
request.headers['Authorization'] = 'Bearer YOUR_TOKEN';
request.fields['broadcastName'] = 'Company Announcements';
request.fields['peerIds'] = jsonEncode([
  '64a1b2c3d4e5f6a7b8c9d0e2',
  '64a1b2c3d4e5f6a7b8c9d0e3',
  '64a1b2c3d4e5f6a7b8c9d0e4',
]);
request.files.add(await http.MultipartFile.fromPath('file', imagePath));
final response = await request.send();

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "uId": "64a1b2c3d4e5f6a7b8c9d0e1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "rT": "b",
    "t": "Company Announcements",
    "tEn": "Company Announcements",
    "nTitle": null,
    "img": "https://s3.amazonaws.com/weellu/broadcasts/64f1a2b3.jpg",
    "isD": false,
    "isA": false,
    "isM": false,
    "isPin": false,
    "tTo": null,
    "chatWallpaper": null,
    "lastMsgId": null,
    "uC": 0,
    "mentionsCount": 0,
    "createdAt": "2026-03-18T12:00:00.000Z"
  },
  "msg": null
}

Get Broadcast Info

GET https://api.weellu.com/api/v1/channel/:roomId/broadcast/info

Returns the broadcast settings and metadata (name, image, creator, linked groups and projects).

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the broadcast room

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/info" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/info",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/info',
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d2",
    "cId": "64a1b2c3d4e5f6a7b8c9d0e1",
    "bName": "Company Announcements",
    "bImg": "https://s3.amazonaws.com/weellu/broadcasts/64f1a2b3.jpg",
    "groups": [],
    "projects": []
  },
  "msg": null
}

Get My Broadcast Info

GET https://api.weellu.com/api/v1/channel/:roomId/broadcast/my-info

Returns the authenticated user's room member record for the broadcast channel.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the broadcast room

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/my-info" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/my-info",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/my-info',
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "uId": "64a1b2c3d4e5f6a7b8c9d0e1",
    "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "rT": "b",
    "t": "Company Announcements",
    "tEn": "Company Announcements",
    "nTitle": null,
    "img": "https://s3.amazonaws.com/weellu/broadcasts/64f1a2b3.jpg",
    "isD": false,
    "isA": false,
    "isM": false,
    "isPin": false,
    "tTo": null,
    "chatWallpaper": null,
    "uC": 2,
    "mentionsCount": 0,
    "createdAt": "2026-03-01T08:00:00.000Z"
  },
  "msg": null
}

List Broadcast Members

GET https://api.weellu.com/api/v1/channel/:roomId/broadcast/members

Returns a paginated list of broadcast members. Supports searching by name and cursor-based pagination.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the broadcast room

Query Parameters

Parameter Type Required Description
page number No Page number (default: 1)
limit number No Items per page (default: 20)
lastId string No Last member ID for cursor-based pagination
fullName string No Search members by full name (partial match)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/members?page=1&limit=20" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/members?page=1&limit=20",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/members',
  parameters: {'page': '1', 'limit': '20'},
);

Example Response

{
  "code": 2000,
  "data": {
    "docs": [
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0a1",
        "uId": "64a1b2c3d4e5f6a7b8c9d0e1",
        "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "bId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "role": "superAdmin",
        "userData": {
          "_id": "64a1b2c3d4e5f6a7b8c9d0e1",
          "fullName": "Alice Johnson",
          "img": "https://s3.amazonaws.com/weellu/avatars/alice.jpg",
          "bio": "CEO"
        },
        "createdAt": "2026-03-01T08:00:00.000Z"
      },
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0a2",
        "uId": "64a1b2c3d4e5f6a7b8c9d0e2",
        "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "bId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "role": "admin",
        "userData": {
          "_id": "64a1b2c3d4e5f6a7b8c9d0e2",
          "fullName": "Bob Williams",
          "img": "https://s3.amazonaws.com/weellu/avatars/bob.jpg",
          "bio": "VP Engineering"
        },
        "createdAt": "2026-03-01T08:05:00.000Z"
      },
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0a3",
        "uId": "64a1b2c3d4e5f6a7b8c9d0e3",
        "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "bId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "role": "member",
        "userData": {
          "_id": "64a1b2c3d4e5f6a7b8c9d0e3",
          "fullName": "Carol Davis",
          "img": "https://s3.amazonaws.com/weellu/avatars/carol.jpg",
          "bio": "Designer"
        },
        "createdAt": "2026-03-02T10:00:00.000Z"
      }
    ],
    "totalDocs": 50,
    "limit": 20,
    "page": 1,
    "totalPages": 3,
    "hasNextPage": true,
    "hasPrevPage": false
  },
  "msg": null
}

List Broadcast Members V2

GET https://api.weellu.com/api/v1/channel/:roomId/broadcast/members/v2

Returns broadcast members using the v2 endpoint with enhanced query capabilities.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the broadcast room

Query Parameters

Parameter Type Required Description
page number No Page number (default: 1)
limit number No Items per page (default: 20)
fullName string No Search members by full name

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/members/v2?page=1&limit=10" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/members/v2?page=1&limit=10",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/members/v2',
  parameters: {'page': '1', 'limit': '10'},
);

Example Response

{
  "code": 2000,
  "data": {
    "docs": [
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0a1",
        "uId": "64a1b2c3d4e5f6a7b8c9d0e1",
        "rId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "bId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "role": "superAdmin",
        "userData": {
          "_id": "64a1b2c3d4e5f6a7b8c9d0e1",
          "fullName": "Alice Johnson",
          "img": "https://s3.amazonaws.com/weellu/avatars/alice.jpg",
          "bio": "CEO"
        },
        "createdAt": "2026-03-01T08:00:00.000Z"
      }
    ],
    "totalDocs": 50,
    "limit": 10,
    "page": 1,
    "totalPages": 5,
    "hasNextPage": true,
    "hasPrevPage": false
  },
  "msg": null
}

Add Members to Broadcast

POST https://api.weellu.com/api/v1/channel/:roomId/broadcast/members

Adds one or more members to an existing broadcast channel.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the broadcast room

Body Parameters

Parameter Type Required Description
ids array Yes Array of MongoDB ObjectIds of users to add

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/members" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"ids": ["64a1b2c3d4e5f6a7b8c9d0e5", "64a1b2c3d4e5f6a7b8c9d0e6"]}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/members",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      ids: ["64a1b2c3d4e5f6a7b8c9d0e5", "64a1b2c3d4e5f6a7b8c9d0e6"]
    })
  }
);
const data = await response.json();
final response = await chopper.post(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/members',
  body: {
    'ids': ['64a1b2c3d4e5f6a7b8c9d0e5', '64a1b2c3d4e5f6a7b8c9d0e6'],
  },
);

Example Response

{
  "code": 2000,
  "data": null,
  "msg": null
}

Kick Broadcast Member

DELETE https://api.weellu.com/api/v1/channel/:roomId/broadcast/members/:peerId

Removes a member from the broadcast channel. Only admins and super admins can remove members.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the broadcast room
peerId string Yes MongoDB ObjectId of the user to remove

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/members/64a1b2c3d4e5f6a7b8c9d0e3" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/members/64a1b2c3d4e5f6a7b8c9d0e3",
  {
    method: "DELETE",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/members/64a1b2c3d4e5f6a7b8c9d0e3',
);

Example Response

{
  "code": 2000,
  "data": null,
  "msg": null
}

Update Broadcast Title

PATCH https://api.weellu.com/api/v1/channel/:roomId/broadcast/title

Updates the display name of the broadcast channel. Only admins and super admins can update the title.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the broadcast room

Body Parameters

Parameter Type Required Description
title string Yes The new broadcast title

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/title" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Product Updates & Releases"}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/title",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ title: "Product Updates & Releases" })
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/title',
  body: {'title': 'Product Updates & Releases'},
);

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d2",
    "bName": "Product Updates & Releases"
  },
  "msg": null
}

Update Broadcast Image

PATCH https://api.weellu.com/api/v1/channel/:roomId/broadcast/image

Updates the broadcast channel avatar image. Only admins and super admins can update the image.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the broadcast room

Body Parameters (multipart/form-data)

Parameter Type Required Description
file file Yes Image file to upload (JPEG, PNG, etc.)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/image" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "file=@/path/to/new-broadcast-image.jpg"
const formData = new FormData();
formData.append("file", imageFile);

const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/image",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    },
    body: formData
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'PATCH',
  Uri.parse('https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/image'),
);
request.headers['Authorization'] = 'Bearer YOUR_TOKEN';
request.files.add(await http.MultipartFile.fromPath('file', imagePath));
final response = await request.send();

Example Response

{
  "code": 2000,
  "data": {
    "_id": "64f1a2b3c4d5e6f7a8b9c0d2",
    "bImg": "https://s3.amazonaws.com/weellu/broadcasts/64f1a2b3-new.jpg"
  },
  "msg": null
}

Add Admin to Broadcast

POST https://api.weellu.com/api/v1/channel/broadcast/:broadcastId/user/:peerId

Promotes a broadcast member to admin role. Only the super admin can promote members.

Path Parameters

Parameter Type Required Description
broadcastId string Yes MongoDB ObjectId of the broadcast
peerId string Yes MongoDB ObjectId of the user to promote

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/broadcast/64f1a2b3c4d5e6f7a8b9c0d2/user/64a1b2c3d4e5f6a7b8c9d0e3" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/broadcast/64f1a2b3c4d5e6f7a8b9c0d2/user/64a1b2c3d4e5f6a7b8c9d0e3",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.post(
  '/channel/broadcast/64f1a2b3c4d5e6f7a8b9c0d2/user/64a1b2c3d4e5f6a7b8c9d0e3',
);

Example Response

{
  "code": 2000,
  "data": null,
  "msg": null
}

Remove Admin from Broadcast

DELETE https://api.weellu.com/api/v1/channel/broadcast/:broadcastId/user/:peerId

Demotes a broadcast admin back to member role. Only the super admin can demote admins.

Path Parameters

Parameter Type Required Description
broadcastId string Yes MongoDB ObjectId of the broadcast
peerId string Yes MongoDB ObjectId of the admin to demote

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/broadcast/64f1a2b3c4d5e6f7a8b9c0d2/user/64a1b2c3d4e5f6a7b8c9d0e3" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/broadcast/64f1a2b3c4d5e6f7a8b9c0d2/user/64a1b2c3d4e5f6a7b8c9d0e3",
  {
    method: "DELETE",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/channel/broadcast/64f1a2b3c4d5e6f7a8b9c0d2/user/64a1b2c3d4e5f6a7b8c9d0e3',
);

Example Response

{
  "code": 2000,
  "data": null,
  "msg": null
}

Get Broadcast Message Status

GET https://api.weellu.com/api/v1/channel/:roomId/broadcast/message/:messageId/status/:type

Returns the delivery or seen status of a specific message for all broadcast members. Supports pagination.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the broadcast room
messageId string Yes MongoDB ObjectId of the message
type string Yes Status type: seen or deliver

Query Parameters

Parameter Type Required Description
page number No Page number (default: 1)
limit number No Items per page (default: 20)

MessageStatusType Enum

Value Description
seen Members who have read the message
deliver Members who have received (but not necessarily read) the message

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/message/64f1a2b3c4d5e6f7a8b9c0d3/status/seen?page=1&limit=20" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/message/64f1a2b3c4d5e6f7a8b9c0d3/status/seen?page=1&limit=20",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/message/64f1a2b3c4d5e6f7a8b9c0d3/status/seen',
  parameters: {'page': '1', 'limit': '20'},
);

Example Response

{
  "code": 2000,
  "data": {
    "docs": [
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0b1",
        "uId": "64a1b2c3d4e5f6a7b8c9d0e2",
        "userData": {
          "_id": "64a1b2c3d4e5f6a7b8c9d0e2",
          "fullName": "Bob Williams",
          "img": "https://s3.amazonaws.com/weellu/avatars/bob.jpg"
        },
        "date": "2026-03-18T10:32:00.000Z"
      },
      {
        "_id": "64f1a2b3c4d5e6f7a8b9c0b2",
        "uId": "64a1b2c3d4e5f6a7b8c9d0e3",
        "userData": {
          "_id": "64a1b2c3d4e5f6a7b8c9d0e3",
          "fullName": "Carol Davis",
          "img": "https://s3.amazonaws.com/weellu/avatars/carol.jpg"
        },
        "date": "2026-03-18T10:45:00.000Z"
      }
    ],
    "totalDocs": 35,
    "limit": 20,
    "page": 1,
    "totalPages": 2,
    "hasNextPage": true,
    "hasPrevPage": false
  },
  "msg": null
}

Add Projects to Broadcast

PATCH https://api.weellu.com/api/v1/channel/:roomId/broadcast/projects/add

Links project rooms to the broadcast. When a message is sent to the broadcast, it can also be forwarded to linked project rooms.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the broadcast room

Body Parameters

Parameter Type Required Description
ids array Yes Array of MongoDB ObjectIds of project rooms to link

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/projects/add" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"ids": ["64f1a2b3c4d5e6f7a8b9c1a1", "64f1a2b3c4d5e6f7a8b9c1a2"]}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/projects/add",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      ids: ["64f1a2b3c4d5e6f7a8b9c1a1", "64f1a2b3c4d5e6f7a8b9c1a2"]
    })
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/projects/add',
  body: {
    'ids': ['64f1a2b3c4d5e6f7a8b9c1a1', '64f1a2b3c4d5e6f7a8b9c1a2'],
  },
);

Example Response

{
  "code": 2000,
  "data": null,
  "msg": null
}

Remove Projects from Broadcast

DELETE https://api.weellu.com/api/v1/channel/:roomId/broadcast/projects/remove

Unlinks project rooms from the broadcast channel.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the broadcast room

Body Parameters

Parameter Type Required Description
ids array Yes Array of MongoDB ObjectIds of project rooms to unlink

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/projects/remove" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"ids": ["64f1a2b3c4d5e6f7a8b9c1a1"]}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/projects/remove",
  {
    method: "DELETE",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      ids: ["64f1a2b3c4d5e6f7a8b9c1a1"]
    })
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/projects/remove',
  body: {
    'ids': ['64f1a2b3c4d5e6f7a8b9c1a1'],
  },
);

Example Response

{
  "code": 2000,
  "data": null,
  "msg": null
}

List Broadcast Projects

GET https://api.weellu.com/api/v1/channel/:roomId/broadcast/projects

Returns the list of project rooms linked to the broadcast channel.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the broadcast room

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/projects" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/projects",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/projects',
);

Example Response

{
  "code": 2000,
  "data": [
    {
      "_id": "64f1a2b3c4d5e6f7a8b9c1a1",
      "rT": "p",
      "t": "Mobile App Project",
      "img": "https://s3.amazonaws.com/weellu/projects/mobile.jpg"
    },
    {
      "_id": "64f1a2b3c4d5e6f7a8b9c1a2",
      "rT": "p",
      "t": "Backend API Project",
      "img": "https://s3.amazonaws.com/weellu/projects/backend.jpg"
    }
  ],
  "msg": null
}

Add Groups to Broadcast

PATCH https://api.weellu.com/api/v1/channel/:roomId/broadcast/groups/add

Links group chat rooms to the broadcast. When a message is sent to the broadcast, it can also be forwarded to linked group rooms.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the broadcast room

Body Parameters

Parameter Type Required Description
ids array Yes Array of MongoDB ObjectIds of group rooms to link

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/groups/add" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"ids": ["64f1a2b3c4d5e6f7a8b9c2a1", "64f1a2b3c4d5e6f7a8b9c2a2"]}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/groups/add",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      ids: ["64f1a2b3c4d5e6f7a8b9c2a1", "64f1a2b3c4d5e6f7a8b9c2a2"]
    })
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/groups/add',
  body: {
    'ids': ['64f1a2b3c4d5e6f7a8b9c2a1', '64f1a2b3c4d5e6f7a8b9c2a2'],
  },
);

Example Response

{
  "code": 2000,
  "data": null,
  "msg": null
}

Remove Groups from Broadcast

DELETE https://api.weellu.com/api/v1/channel/:roomId/broadcast/groups/remove

Unlinks group chat rooms from the broadcast channel.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the broadcast room

Body Parameters

Parameter Type Required Description
ids array Yes Array of MongoDB ObjectIds of group rooms to unlink

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/groups/remove" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"ids": ["64f1a2b3c4d5e6f7a8b9c2a1"]}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/groups/remove",
  {
    method: "DELETE",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      ids: ["64f1a2b3c4d5e6f7a8b9c2a1"]
    })
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/groups/remove',
  body: {
    'ids': ['64f1a2b3c4d5e6f7a8b9c2a1'],
  },
);

Example Response

{
  "code": 2000,
  "data": null,
  "msg": null
}

List Broadcast Groups

GET https://api.weellu.com/api/v1/channel/:roomId/broadcast/groups

Returns the list of group chat rooms linked to the broadcast channel.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the broadcast room

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/groups" \
  -H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/groups",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN"
    }
  }
);
const data = await response.json();
final response = await chopper.get(
  '/channel/64f1a2b3c4d5e6f7a8b9c0d2/broadcast/groups',
);

Example Response

{
  "code": 2000,
  "data": [
    {
      "_id": "64f1a2b3c4d5e6f7a8b9c2a1",
      "rT": "g",
      "t": "Engineering Team",
      "img": "https://s3.amazonaws.com/weellu/groups/eng-team.jpg"
    },
    {
      "_id": "64f1a2b3c4d5e6f7a8b9c2a2",
      "rT": "g",
      "t": "Design Team",
      "img": "https://s3.amazonaws.com/weellu/groups/design-team.jpg"
    }
  ],
  "msg": null
}

Projects

Project channels are advanced rooms designed for team collaboration, task management, and integrations. All endpoints require authentication via Authorization: Bearer TOKEN.

Base URL: https://api.weellu.com/api/v1/channel

Create Project

POST https://api.weellu.com/api/v1/channel/project

Creates a new project channel. Supports multipart form data for an optional project image.

Parameters

Parameter Type Required Description
projectName string Yes Name of the project
peerIds string[] Yes Array of user IDs to add as initial members (JSON-encoded array)
file file No Project image (multipart upload)

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/project" \
  -H "Authorization: Bearer TOKEN" \
  -F 'projectName=Sprint Q2 2026' \
  -F 'peerIds=["665a1f2e3b4c5d6e7f8a9b0c","665a1f2e3b4c5d6e7f8a9b0d"]' \
  -F 'file=@/path/to/image.png'
const formData = new FormData();
formData.append("projectName", "Sprint Q2 2026");
formData.append("peerIds", JSON.stringify([
  "665a1f2e3b4c5d6e7f8a9b0c",
  "665a1f2e3b4c5d6e7f8a9b0d"
]));
formData.append("file", imageFile);

const response = await fetch("https://api.weellu.com/api/v1/channel/project", {
  method: "POST",
  headers: { "Authorization": "Bearer TOKEN" },
  body: formData
});
const data = await response.json();
final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/channel/project'),
);
request.headers['Authorization'] = 'Bearer TOKEN';
request.fields['projectName'] = 'Sprint Q2 2026';
request.fields['peerIds'] = jsonEncode([
  '665a1f2e3b4c5d6e7f8a9b0c',
  '665a1f2e3b4c5d6e7f8a9b0d',
]);
request.files.add(await http.MultipartFile.fromPath('file', '/path/to/image.png'));
final response = await request.send();

Example Response

{
  "code": 200,
  "data": {
    "_id": "665b2a3c4d5e6f7a8b9c0d1e",
    "title": "Sprint Q2 2026",
    "roomType": "p",
    "image": "https://cdn.weellu.com/projects/665b2a3c4d5e6f7a8b9c0d1e.png",
    "createdAt": "2026-03-18T10:30:00.000Z"
  }
}

Get Project Info

GET https://api.weellu.com/api/v1/channel/:roomId/project/info

Retrieves full project information including settings, members count, and configuration.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/info" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/info",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/info'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "665b2a3c4d5e6f7a8b9c0d1e",
    "title": "Sprint Q2 2026",
    "roomType": "p",
    "image": "https://cdn.weellu.com/projects/665b2a3c4d5e6f7a8b9c0d1e.png",
    "membersCount": 12,
    "createdAt": "2026-03-18T10:30:00.000Z",
    "updatedAt": "2026-03-18T14:00:00.000Z"
  }
}

Get My Project Info

GET https://api.weellu.com/api/v1/channel/:roomId/project/my-info

Retrieves the current user's membership information within a project, including their role and settings.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/my-info" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/my-info",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/my-info'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": {
    "role": "admin",
    "isMuted": false,
    "joinedAt": "2026-03-18T10:30:00.000Z"
  }
}

Destroy Project

DELETE https://api.weellu.com/api/v1/channel/:roomId/project/destroy

Permanently deletes a project channel. Only the super admin can perform this action.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/destroy" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/destroy",
  { method: "DELETE", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.delete(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/destroy'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Update Project Title

PATCH https://api.weellu.com/api/v1/channel/:roomId/project/title

Updates the project channel title. Requires admin or super admin role.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
title string Yes New project title (body)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/title" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Sprint Q3 2026"}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/title",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ title: "Sprint Q3 2026" })
  }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/title'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({'title': 'Sprint Q3 2026'}),
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Update Project Image

PATCH https://api.weellu.com/api/v1/channel/:roomId/project/image

Updates the project channel image. Multipart form data with an image file is required.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
file file Yes New project image (multipart upload)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/image" \
  -H "Authorization: Bearer TOKEN" \
  -F 'file=@/path/to/new-image.png'
const formData = new FormData();
formData.append("file", imageFile);

const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/image",
  {
    method: "PATCH",
    headers: { "Authorization": "Bearer TOKEN" },
    body: formData
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'PATCH',
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/image'),
);
request.headers['Authorization'] = 'Bearer TOKEN';
request.files.add(await http.MultipartFile.fromPath('file', '/path/to/new-image.png'));
final response = await request.send();

Example Response

{
  "code": 200,
  "data": "Done"
}

Get User Super Projects

GET https://api.weellu.com/api/v1/channel/project/user-super-projects

Retrieves all projects where the current user is a super admin.

Parameters

Parameter Type Required Description
page string No Page number (default: 1)
limit string No Items per page (default: 20)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/project/user-super-projects?page=1&limit=10" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/project/user-super-projects?page=1&limit=10",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/project/user-super-projects?page=1&limit=10'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "665b2a3c4d5e6f7a8b9c0d1e",
      "title": "Sprint Q2 2026",
      "roomType": "p",
      "image": "https://cdn.weellu.com/projects/665b2a3c4d5e6f7a8b9c0d1e.png"
    },
    {
      "_id": "665b2a3c4d5e6f7a8b9c0d2f",
      "title": "Design System",
      "roomType": "p",
      "image": "https://cdn.weellu.com/projects/665b2a3c4d5e6f7a8b9c0d2f.png"
    }
  ]
}

List Members (v2)

GET https://api.weellu.com/api/v1/channel/:roomId/project/members/v2

Retrieves the project members list with pagination (v2 endpoint).

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
page string No Page number (default: 1)
limit string No Items per page (default: 20)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/members/v2?page=1&limit=20" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/members/v2?page=1&limit=20",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/members/v2?page=1&limit=20'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": {
    "docs": [
      {
        "_id": "665a1f2e3b4c5d6e7f8a9b0c",
        "fullName": "John Doe",
        "userImage": "https://cdn.weellu.com/users/665a1f2e3b4c5d6e7f8a9b0c.png",
        "role": "superAdmin"
      },
      {
        "_id": "665a1f2e3b4c5d6e7f8a9b0d",
        "fullName": "Jane Smith",
        "userImage": "https://cdn.weellu.com/users/665a1f2e3b4c5d6e7f8a9b0d.png",
        "role": "member"
      }
    ],
    "totalDocs": 12,
    "limit": 20,
    "page": 1,
    "totalPages": 1
  }
}

Add Members

POST https://api.weellu.com/api/v1/channel/:roomId/project/members

Adds one or more members to the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
ids string[] Yes Array of user MongoDB ObjectIds to add (body)

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/members" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"ids": ["665a1f2e3b4c5d6e7f8a9b0e", "665a1f2e3b4c5d6e7f8a9b0f"]}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/members",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      ids: ["665a1f2e3b4c5d6e7f8a9b0e", "665a1f2e3b4c5d6e7f8a9b0f"]
    })
  }
);
const data = await response.json();
final response = await http.post(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/members'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({
    'ids': ['665a1f2e3b4c5d6e7f8a9b0e', '665a1f2e3b4c5d6e7f8a9b0f'],
  }),
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Kick Member

DELETE https://api.weellu.com/api/v1/channel/:roomId/project/members/:peerId

Removes a member from the project. Requires admin or super admin role.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
peerId string Yes MongoDB ObjectId of the user to remove (path parameter)

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/members/665a1f2e3b4c5d6e7f8a9b0d" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/members/665a1f2e3b4c5d6e7f8a9b0d",
  { method: "DELETE", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.delete(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/members/665a1f2e3b4c5d6e7f8a9b0d'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Update Member Role

PATCH https://api.weellu.com/api/v1/channel/:roomId/project/members/:peerId/:role

Changes a member's role within the project. Only admins and super admins can update roles.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
peerId string Yes MongoDB ObjectId of the target user (path parameter)
role string Yes New role for the user (path parameter)

ProjectRoleType Enum

Value Description
member Regular project member
superAdmin Project owner with full control
assist Assistant role with limited admin capabilities
admin Administrator with management permissions

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/members/665a1f2e3b4c5d6e7f8a9b0d/admin" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/members/665a1f2e3b4c5d6e7f8a9b0d/admin",
  { method: "PATCH", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/members/665a1f2e3b4c5d6e7f8a9b0d/admin'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Transfer Super Admin

PATCH https://api.weellu.com/api/v1/channel/:roomId/project/transfer-super-admin/:peerId

Transfers super admin ownership of the project to another member. Only the current super admin can perform this action.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
peerId string Yes MongoDB ObjectId of the new super admin (path parameter)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/transfer-super-admin/665a1f2e3b4c5d6e7f8a9b0d" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/transfer-super-admin/665a1f2e3b4c5d6e7f8a9b0d",
  { method: "PATCH", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/transfer-super-admin/665a1f2e3b4c5d6e7f8a9b0d'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Leave Project

DELETE https://api.weellu.com/api/v1/channel/:roomId/project/leave

Leaves the project channel. Super admins must transfer ownership before leaving.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/leave" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/leave",
  { method: "DELETE", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.delete(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/leave'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

List Categories

GET https://api.weellu.com/api/v1/channel/:roomId/project/categories

Retrieves all task categories defined for the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/categories" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/categories",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/categories'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "665c3b4d5e6f7a8b9c0d1e2f",
      "title": "Bug Fix",
      "color": "#FF5733",
      "icon": "bug_report"
    },
    {
      "_id": "665c3b4d5e6f7a8b9c0d1e30",
      "title": "Feature",
      "color": "#33FF57",
      "icon": "star"
    }
  ]
}

Create Category

POST https://api.weellu.com/api/v1/channel/:roomId/project/categories

Creates a new task category for the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
title string Yes Category name
color string Yes Hex color code (e.g. #FF5733)
icon string Yes Icon identifier

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/categories" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Improvement", "color": "#3357FF", "icon": "trending_up"}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/categories",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      title: "Improvement",
      color: "#3357FF",
      icon: "trending_up"
    })
  }
);
const data = await response.json();
final response = await http.post(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/categories'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({'title': 'Improvement', 'color': '#3357FF', 'icon': 'trending_up'}),
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "665c3b4d5e6f7a8b9c0d1e31",
    "title": "Improvement",
    "color": "#3357FF",
    "icon": "trending_up"
  }
}

Update Category

PATCH https://api.weellu.com/api/v1/channel/:roomId/project/categories/:categoryId

Updates an existing task category. All fields are optional.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
categoryId string Yes MongoDB ObjectId of the category (path parameter)
title string No New category name
color string No New hex color code
icon string No New icon identifier

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/categories/665c3b4d5e6f7a8b9c0d1e2f" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Critical Bug", "color": "#FF0000"}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/categories/665c3b4d5e6f7a8b9c0d1e2f",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ title: "Critical Bug", color: "#FF0000" })
  }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/categories/665c3b4d5e6f7a8b9c0d1e2f'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({'title': 'Critical Bug', 'color': '#FF0000'}),
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Delete Category

DELETE https://api.weellu.com/api/v1/channel/:roomId/project/categories/:categoryId

Deletes a task category from the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
categoryId string Yes MongoDB ObjectId of the category (path parameter)

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/categories/665c3b4d5e6f7a8b9c0d1e2f" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/categories/665c3b4d5e6f7a8b9c0d1e2f",
  { method: "DELETE", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.delete(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/categories/665c3b4d5e6f7a8b9c0d1e2f'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Filter Tasks (v3)

POST https://api.weellu.com/api/v1/channel/:roomId/project/tasks/v3

Filters and paginates project tasks with advanced criteria. Uses POST to support complex filter body.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
filter string Yes Tab filter for task ownership context (body)
from string (ISO 8601) No Start date for date range filter (body)
to string (ISO 8601) No End date for date range filter (body, required if from is set)
title string No Text search on task title (body)
status string[] No Filter by task status values (body)
flag string[] No Filter by task flag/priority values (body)
categoryIds string[] No Filter by category MongoDB ObjectIds (body)
memberIds string[] No Filter by member/sender MongoDB ObjectIds (body)
withMyMentions boolean No Only show tasks where the current user is mentioned (body)
limit number No Number of results per page (default: 20, must be > 0) (body)
lastUpdateAt string (ISO 8601) No Cursor-based pagination: return tasks updated before this date (body)

TasksTabFilter Enum (filter)

Value Description
my Tasks created by the current user
assets Tasks assigned to the current user
waiting Tasks awaiting action from the current user

TaskStatus Enum (status)

Value Description
open Newly created task
reOpen Reopened after completion
onProgress Work in progress
done Completed
revision Under review
canceled Cancelled
concluded Finalized/concluded
reopenRejected Reopen request was rejected
reScheduled Rescheduled for later

TaskFlag Enum (flag)

Value Description
urgent Urgent priority
veryHigh Very high priority
high High priority
normal Normal priority
low Low priority

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/tasks/v3" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": "my",
    "from": "2026-03-01T00:00:00.000Z",
    "to": "2026-03-31T23:59:59.999Z",
    "status": ["open", "onProgress"],
    "flag": ["urgent", "high"],
    "categoryIds": ["665c3b4d5e6f7a8b9c0d1e2f"],
    "memberIds": ["665a1f2e3b4c5d6e7f8a9b0c"],
    "limit": 20
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/tasks/v3",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      filter: "my",
      from: "2026-03-01T00:00:00.000Z",
      to: "2026-03-31T23:59:59.999Z",
      status: ["open", "onProgress"],
      flag: ["urgent", "high"],
      categoryIds: ["665c3b4d5e6f7a8b9c0d1e2f"],
      memberIds: ["665a1f2e3b4c5d6e7f8a9b0c"],
      limit: 20
    })
  }
);
const data = await response.json();
final response = await http.post(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/tasks/v3'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({
    'filter': 'my',
    'from': '2026-03-01T00:00:00.000Z',
    'to': '2026-03-31T23:59:59.999Z',
    'status': ['open', 'onProgress'],
    'flag': ['urgent', 'high'],
    'categoryIds': ['665c3b4d5e6f7a8b9c0d1e2f'],
    'memberIds': ['665a1f2e3b4c5d6e7f8a9b0c'],
    'limit': 20,
  }),
);

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "665d4c5e6f7a8b9c0d1e2f3a",
      "sId": "665a1f2e3b4c5d6e7f8a9b0c",
      "sName": "John Doe",
      "sImg": "https://cdn.weellu.com/users/665a1f2e3b4c5d6e7f8a9b0c_thumb.png",
      "rId": "665b2a3c4d5e6f7a8b9c0d1e",
      "c": "Fix login page crash on iOS",
      "mT": "task",
      "msgAtt": {
        "title": "Fix login page crash on iOS",
        "status": "open",
        "flag": "urgent",
        "category": {
          "id": "665c3b4d5e6f7a8b9c0d1e2f",
          "title": "Bug Fix",
          "color": "#FF5733"
        }
      },
      "mentions": ["665a1f2e3b4c5d6e7f8a9b0d"],
      "createdAt": "2026-03-15T09:30:00.000Z",
      "updatedAt": "2026-03-18T14:00:00.000Z"
    }
  ]
}

Get Project Activity Logs

GET https://api.weellu.com/api/v1/channel/:roomId/project/activity-logs

Retrieves the activity log for the entire project with pagination.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
page string No Page number (default: 1)
limit string No Items per page (default: 20)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/activity-logs?page=1&limit=20" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/activity-logs?page=1&limit=20",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/activity-logs?page=1&limit=20'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": {
    "docs": [
      {
        "_id": "665e5d6f7a8b9c0d1e2f3a4b",
        "action": "updateTaskStatus",
        "userId": "665a1f2e3b4c5d6e7f8a9b0c",
        "userName": "John Doe",
        "details": {
          "taskTitle": "Fix login page crash",
          "oldStatus": "open",
          "newStatus": "onProgress"
        },
        "createdAt": "2026-03-18T14:05:00.000Z"
      }
    ],
    "totalDocs": 45,
    "limit": 20,
    "page": 1,
    "totalPages": 3
  }
}

List System Messages

GET https://api.weellu.com/api/v1/channel/:roomId/project/system-messages

Retrieves all system messages configured for the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "665f6e7a8b9c0d1e2f3a4b5c",
      "title": "Welcome Message",
      "message": "Welcome to the project! Please read the guidelines."
    }
  ]
}

Create System Message

POST https://api.weellu.com/api/v1/channel/:roomId/project/system-messages

Creates a new system message for the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
title string Yes System message title (body)
message string Yes System message content (body)

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Daily Standup", "message": "Please post your daily update by 10am."}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      title: "Daily Standup",
      message: "Please post your daily update by 10am."
    })
  }
);
const data = await response.json();
final response = await http.post(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({'title': 'Daily Standup', 'message': 'Please post your daily update by 10am.'}),
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "665f6e7a8b9c0d1e2f3a4b5d",
    "title": "Daily Standup",
    "message": "Please post your daily update by 10am."
  }
}

Update System Message

PATCH https://api.weellu.com/api/v1/channel/:roomId/project/system-messages/:messageId

Updates an existing system message.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
messageId string Yes MongoDB ObjectId of the system message (path parameter)
title string Yes Updated title (body)
message string Yes Updated message content (body)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages/665f6e7a8b9c0d1e2f3a4b5d" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Daily Standup Updated", "message": "Please post your daily update by 9:30am."}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages/665f6e7a8b9c0d1e2f3a4b5d",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      title: "Daily Standup Updated",
      message: "Please post your daily update by 9:30am."
    })
  }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages/665f6e7a8b9c0d1e2f3a4b5d'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({'title': 'Daily Standup Updated', 'message': 'Please post your daily update by 9:30am.'}),
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Delete System Message

DELETE https://api.weellu.com/api/v1/channel/:roomId/project/system-messages/:messageId

Deletes a single system message.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
messageId string Yes MongoDB ObjectId of the system message (path parameter)

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages/665f6e7a8b9c0d1e2f3a4b5d" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages/665f6e7a8b9c0d1e2f3a4b5d",
  { method: "DELETE", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.delete(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages/665f6e7a8b9c0d1e2f3a4b5d'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Delete All System Messages

DELETE https://api.weellu.com/api/v1/channel/:roomId/project/system-messages

Deletes all system messages for the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages",
  { method: "DELETE", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.delete(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Toggle System Messages Setting

PATCH https://api.weellu.com/api/v1/channel/:roomId/project/system-messages

Batch updates the system messages configuration for the project (replaces all messages).

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
messages object[] Yes Array of system message objects (body)
messages[].title string Yes System message title
messages[].message string Yes System message content

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {"title": "Welcome", "message": "Welcome to the project!"},
      {"title": "Rules", "message": "Follow the coding standards."}
    ]
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      messages: [
        { title: "Welcome", message: "Welcome to the project!" },
        { title: "Rules", message: "Follow the coding standards." }
      ]
    })
  }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/system-messages'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({
    'messages': [
      {'title': 'Welcome', 'message': 'Welcome to the project!'},
      {'title': 'Rules', 'message': 'Follow the coding standards.'},
    ]
  }),
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Add Menu

POST https://api.weellu.com/api/v1/channel/:roomId/project/menu/:id

Adds a menu item to the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
id string Yes MongoDB ObjectId of the menu item to add (path parameter)

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/menu/665f7a8b9c0d1e2f3a4b5c6d" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/menu/665f7a8b9c0d1e2f3a4b5c6d",
  { method: "POST", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.post(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/menu/665f7a8b9c0d1e2f3a4b5c6d'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Delete Menu

DELETE https://api.weellu.com/api/v1/channel/:roomId/project/menu/delete

Removes the menu from the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/menu/delete" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/menu/delete",
  { method: "DELETE", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.delete(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/menu/delete'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

IXC Integration: Set Config

PATCH https://api.weellu.com/api/v1/channel/:roomId/ixc-integration/config

Configures IXC integration credentials for the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
token string Yes IXC API authentication token (body)
host string Yes IXC API host URL (body)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/ixc-integration/config" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"token": "ixc_api_token_abc123", "host": "https://ixc.example.com"}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/ixc-integration/config",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      token: "ixc_api_token_abc123",
      host: "https://ixc.example.com"
    })
  }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/ixc-integration/config'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({'token': 'ixc_api_token_abc123', 'host': 'https://ixc.example.com'}),
);

Example Response

{
  "code": 200,
  "data": "Done"
}

IXC Integration: Enable

PATCH https://api.weellu.com/api/v1/channel/:roomId/ixc-integration/enabled

Enables IXC integration for the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/ixc-integration/enabled" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/ixc-integration/enabled",
  { method: "PATCH", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/ixc-integration/enabled'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

IXC Integration: Disable

PATCH https://api.weellu.com/api/v1/channel/:roomId/ixc-integration/disable

Disables IXC integration for the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/ixc-integration/disable" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/ixc-integration/disable",
  { method: "PATCH", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/ixc-integration/disable'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

IXC Integration: Get Config

GET https://api.weellu.com/api/v1/channel/:roomId/ixc-integration/getConfig

Retrieves the current IXC integration configuration.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/ixc-integration/getConfig" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/ixc-integration/getConfig",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/ixc-integration/getConfig'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": {
    "token": "ixc_api_token_abc123",
    "host": "https://ixc.example.com",
    "enabled": true
  }
}

IXC Integration: Status

GET https://api.weellu.com/api/v1/channel/:roomId/ixc-integration/status

Retrieves the current IXC integration status (enabled/disabled).

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/ixc-integration/status" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/ixc-integration/status",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/ixc-integration/status'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": {
    "enabled": true
  }
}

Fibranossa Integration: Get Config

GET https://api.weellu.com/api/v1/channel/:roomId/fibranossa-integration/config

Retrieves the Fibranossa integration configuration for the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/fibranossa-integration/config" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/fibranossa-integration/config",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/fibranossa-integration/config'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": {
    "token": "fibranossa_token_xyz789",
    "enabled": true
  }
}

Fibranossa Integration: Set Token

PATCH https://api.weellu.com/api/v1/channel/:roomId/fibranossa-integration/token

Sets the Fibranossa integration authentication token.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
token string Yes Fibranossa API token (body)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/fibranossa-integration/token" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"token": "fibranossa_token_xyz789"}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/fibranossa-integration/token",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ token: "fibranossa_token_xyz789" })
  }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/fibranossa-integration/token'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({'token': 'fibranossa_token_xyz789'}),
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Fibranossa Integration: Toggle Status

PATCH https://api.weellu.com/api/v1/channel/:roomId/fibranossa-integration/status

Toggles the Fibranossa integration on or off.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/fibranossa-integration/status" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/fibranossa-integration/status",
  { method: "PATCH", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/fibranossa-integration/status'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Location Sharing: Enable

PATCH https://api.weellu.com/api/v1/channel/:roomId/location-sharing/enable

Enables location sharing for the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/location-sharing/enable" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/location-sharing/enable",
  { method: "PATCH", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/location-sharing/enable'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Location Sharing: Disable

PATCH https://api.weellu.com/api/v1/channel/:roomId/location-sharing/disable

Disables location sharing for the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/location-sharing/disable" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/location-sharing/disable",
  { method: "PATCH", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/location-sharing/disable'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Location Sharing: Status

GET https://api.weellu.com/api/v1/channel/:roomId/location-sharing/status

Retrieves the current location sharing status for the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/location-sharing/status" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/location-sharing/status",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/location-sharing/status'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": {
    "enabled": true
  }
}

Tracking: Start

PATCH https://api.weellu.com/api/v1/channel/:roomId/project/tracking/start

Starts real-time location tracking for the current user in the project. Joins the user to the project tracking Socket.IO room.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
latitude number No Initial latitude coordinate (body)
longitude number No Initial longitude coordinate (body)
userName string No Display name for tracking (body)
avatar string No Avatar URL for tracking display (body)
start boolean No Explicit start flag (body)
taskId string No Associated task ID (body)
route object[] No Array of initial route points (body)
route[].latitude number Yes Route point latitude
route[].longitude number Yes Route point longitude
route[].timestamp number No Route point Unix timestamp (milliseconds)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/tracking/start" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "latitude": -23.5505,
    "longitude": -46.6333,
    "userName": "John Doe",
    "start": true,
    "taskId": "665d4c5e6f7a8b9c0d1e2f3a"
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/tracking/start",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      latitude: -23.5505,
      longitude: -46.6333,
      userName: "John Doe",
      start: true,
      taskId: "665d4c5e6f7a8b9c0d1e2f3a"
    })
  }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/tracking/start'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({
    'latitude': -23.5505,
    'longitude': -46.6333,
    'userName': 'John Doe',
    'start': true,
    'taskId': '665d4c5e6f7a8b9c0d1e2f3a',
  }),
);

Example Response

{
  "code": 200,
  "data": {
    "tracking": true,
    "startedAt": "2026-03-18T14:30:00.000Z"
  }
}

Tracking: Update

PATCH https://api.weellu.com/api/v1/channel/:roomId/project/tracking/update

Updates the current user's tracking location.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
latitude number Yes Current latitude coordinate (body)
longitude number Yes Current longitude coordinate (body)
isMoving boolean No Whether the user is currently moving (body)
taskId string No Associated task ID (body)
status string No Current tracking status (body)
route object[] No Array of route points since last update (body)
route[].latitude number Yes Route point latitude
route[].longitude number Yes Route point longitude
route[].timestamp number No Route point Unix timestamp (milliseconds)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/tracking/update" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "latitude": -23.5510,
    "longitude": -46.6340,
    "isMoving": true,
    "route": [
      {"latitude": -23.5507, "longitude": -46.6336, "timestamp": 1710772200000},
      {"latitude": -23.5510, "longitude": -46.6340, "timestamp": 1710772260000}
    ]
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/tracking/update",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      latitude: -23.5510,
      longitude: -46.6340,
      isMoving: true,
      route: [
        { latitude: -23.5507, longitude: -46.6336, timestamp: 1710772200000 },
        { latitude: -23.5510, longitude: -46.6340, timestamp: 1710772260000 }
      ]
    })
  }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/tracking/update'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({
    'latitude': -23.5510,
    'longitude': -46.6340,
    'isMoving': true,
    'route': [
      {'latitude': -23.5507, 'longitude': -46.6336, 'timestamp': 1710772200000},
      {'latitude': -23.5510, 'longitude': -46.6340, 'timestamp': 1710772260000},
    ],
  }),
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Tracking: Stop

PATCH https://api.weellu.com/api/v1/channel/:roomId/project/tracking/stop

Stops real-time location tracking for the current user. Removes the user from the project tracking Socket.IO room.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
stop boolean No Explicit stop flag (body)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/tracking/stop" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"stop": true}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/tracking/stop",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ stop: true })
  }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/tracking/stop'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({'stop': true}),
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Tracking: Get

GET https://api.weellu.com/api/v1/channel/:roomId/project/tracking

Retrieves all active tracking sessions for the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/tracking" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/tracking",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/project/tracking'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": [
    {
      "userId": "665a1f2e3b4c5d6e7f8a9b0c",
      "userName": "John Doe",
      "avatar": "https://cdn.weellu.com/users/665a1f2e3b4c5d6e7f8a9b0c.png",
      "latitude": -23.5510,
      "longitude": -46.6340,
      "isMoving": true,
      "taskId": "665d4c5e6f7a8b9c0d1e2f3a",
      "startedAt": "2026-03-18T14:30:00.000Z",
      "updatedAt": "2026-03-18T14:35:00.000Z"
    }
  ]
}

Messages

Message endpoints handle sending, retrieving, and managing messages within chat rooms (single, group, broadcast, and project). All endpoints require authentication via Authorization: Bearer TOKEN.

Base URL: https://api.weellu.com/api/v1/channel/:roomId/message

Send Message

POST https://api.weellu.com/api/v1/channel/:roomId/message/

Sends a message to a room. Supports multipart form data with up to 4 file attachments. For media message types (image, voice, video, file), at least one file is required unless forwarding.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the target room (path parameter)
messageType string Yes Type of message being sent (body)
content string Conditional Text content of the message. Required for text type; optional for media types (body)
localId string (UUID v4) Yes Client-generated UUID for idempotency and local message tracking (body)
parentId string No MongoDB ObjectId of the parent task message (for task sub-messages) (body)
attachment string (JSON) Conditional JSON-encoded attachment metadata. Required for image, video, location, task, and voice types (body)
mentions string[] No Array of user MongoDB ObjectIds to mention. Can also be a comma-separated string (body)
forwardLocalId string (UUID v4) No Local ID of the original message being forwarded (body)
replyToLocalId string (UUID v4) No Local ID of the message being replied to (body)
replyToProduct string No MongoDB ObjectId of a product being replied to (body)
storyId string No MongoDB ObjectId of the story (required when messageType is story) (body)
linkAtt string (JSON) No JSON-encoded link preview attachment (body)
shareUserIds string[] No Array of user IDs to share (when messageType is userShare) (body)
shareUserId string No Single user ID to share (when messageType is userShare and shareUserIds is not set) (body)
broadcastCategory string No Category filter for broadcast messages (body)
file file[] Conditional Up to 4 files via multipart upload. Required for image, voice, video, file types (body)

MessageType Enum

Value Description
text Plain text message
voice Voice recording
image Image attachment
video Video attachment
file Generic file attachment
location Geographic location
task Task message (project rooms only)
call Call event message
story Story reference
sticker Sticker message
userShare User profile share
info System info message (does not trigger notifications)

BroadcastSendCategoryType Enum (broadcastCategory)

Value Description
all Send to all broadcast members
people Send to individual contacts only
groups Send to groups only
projects Send to projects only

Example Request (text message)

curl -X POST "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/" \
  -H "Authorization: Bearer TOKEN" \
  -F 'messageType=text' \
  -F 'content=Hello team! Please review the latest PR.' \
  -F 'localId=550e8400-e29b-41d4-a716-446655440000' \
  -F 'mentions=665a1f2e3b4c5d6e7f8a9b0c,665a1f2e3b4c5d6e7f8a9b0d'
const formData = new FormData();
formData.append("messageType", "text");
formData.append("content", "Hello team! Please review the latest PR.");
formData.append("localId", "550e8400-e29b-41d4-a716-446655440000");
formData.append("mentions", "665a1f2e3b4c5d6e7f8a9b0c,665a1f2e3b4c5d6e7f8a9b0d");

const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/",
  {
    method: "POST",
    headers: { "Authorization": "Bearer TOKEN" },
    body: formData
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/'),
);
request.headers['Authorization'] = 'Bearer TOKEN';
request.fields['messageType'] = 'text';
request.fields['content'] = 'Hello team! Please review the latest PR.';
request.fields['localId'] = '550e8400-e29b-41d4-a716-446655440000';
request.fields['mentions'] = '665a1f2e3b4c5d6e7f8a9b0c,665a1f2e3b4c5d6e7f8a9b0d';
final response = await request.send();

Example Request (image message)

curl -X POST "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/" \
  -H "Authorization: Bearer TOKEN" \
  -F 'messageType=image' \
  -F 'content=Check this screenshot' \
  -F 'localId=550e8400-e29b-41d4-a716-446655440001' \
  -F 'attachment={"width":1920,"height":1080}' \
  -F 'file=@/path/to/screenshot.png'
const formData = new FormData();
formData.append("messageType", "image");
formData.append("content", "Check this screenshot");
formData.append("localId", "550e8400-e29b-41d4-a716-446655440001");
formData.append("attachment", JSON.stringify({ width: 1920, height: 1080 }));
formData.append("file", imageFile);

const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/",
  {
    method: "POST",
    headers: { "Authorization": "Bearer TOKEN" },
    body: formData
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/'),
);
request.headers['Authorization'] = 'Bearer TOKEN';
request.fields['messageType'] = 'image';
request.fields['content'] = 'Check this screenshot';
request.fields['localId'] = '550e8400-e29b-41d4-a716-446655440001';
request.fields['attachment'] = jsonEncode({'width': 1920, 'height': 1080});
request.files.add(await http.MultipartFile.fromPath('file', '/path/to/screenshot.png'));
final response = await request.send();

Example Request (task message)

curl -X POST "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/" \
  -H "Authorization: Bearer TOKEN" \
  -F 'messageType=task' \
  -F 'content=Fix the payment gateway timeout issue' \
  -F 'localId=550e8400-e29b-41d4-a716-446655440002' \
  -F 'attachment={"title":"Fix payment gateway timeout","status":"open","flag":"urgent"}' \
  -F 'mentions=665a1f2e3b4c5d6e7f8a9b0c'
const formData = new FormData();
formData.append("messageType", "task");
formData.append("content", "Fix the payment gateway timeout issue");
formData.append("localId", "550e8400-e29b-41d4-a716-446655440002");
formData.append("attachment", JSON.stringify({
  title: "Fix payment gateway timeout",
  status: "open",
  flag: "urgent"
}));
formData.append("mentions", "665a1f2e3b4c5d6e7f8a9b0c");

const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/",
  {
    method: "POST",
    headers: { "Authorization": "Bearer TOKEN" },
    body: formData
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/'),
);
request.headers['Authorization'] = 'Bearer TOKEN';
request.fields['messageType'] = 'task';
request.fields['content'] = 'Fix the payment gateway timeout issue';
request.fields['localId'] = '550e8400-e29b-41d4-a716-446655440002';
request.fields['attachment'] = jsonEncode({
  'title': 'Fix payment gateway timeout',
  'status': 'open',
  'flag': 'urgent',
});
request.fields['mentions'] = '665a1f2e3b4c5d6e7f8a9b0c';
final response = await request.send();

Example Response

{
  "code": 200,
  "data": {
    "_id": "665d4c5e6f7a8b9c0d1e2f3a",
    "sId": "665a1f2e3b4c5d6e7f8a9b0c",
    "sName": "John Doe",
    "sImg": "https://cdn.weellu.com/users/665a1f2e3b4c5d6e7f8a9b0c_thumb.png",
    "plm": "Android",
    "rId": "665b2a3c4d5e6f7a8b9c0d1e",
    "c": "Hello team! Please review the latest PR.",
    "mT": "text",
    "msgAtt": null,
    "rTo": null,
    "lId": "550e8400-e29b-41d4-a716-446655440000",
    "mentions": ["665a1f2e3b4c5d6e7f8a9b0c", "665a1f2e3b4c5d6e7f8a9b0d"],
    "mentionAll": false,
    "stars": [],
    "reactions": [],
    "isEdited": false,
    "parentId": null,
    "createdAt": "2026-03-18T14:30:00.000Z",
    "updatedAt": "2026-03-18T14:30:00.000Z"
  }
}

Send Multipart Message

POST https://api.weellu.com/api/v1/channel/:roomId/message/multipart

Sends a message using JSON body instead of multipart form data. Useful for text-only or pre-uploaded content. File uploads are not supported on this endpoint.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the target room (path parameter)
messageType string Yes Type of message (body, JSON)
content string Conditional Message text content (body, JSON)
localId string (UUID v4) Yes Client-generated UUID (body, JSON)
parentId string No Parent task message ID (body, JSON)
attachment string (JSON) No JSON-encoded attachment metadata (body, JSON)
mentions string[] No Array of mentioned user IDs (body, JSON)
forwardLocalId string (UUID v4) No Local ID of forwarded message (body, JSON)
replyToLocalId string (UUID v4) No Local ID of replied message (body, JSON)
linkAtt string (JSON) No JSON-encoded link preview (body, JSON)

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/multipart" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "messageType": "text",
    "content": "Meeting starts in 10 minutes!",
    "localId": "550e8400-e29b-41d4-a716-446655440003"
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/multipart",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      messageType: "text",
      content: "Meeting starts in 10 minutes!",
      localId: "550e8400-e29b-41d4-a716-446655440003"
    })
  }
);
const data = await response.json();
final response = await http.post(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/multipart'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({
    'messageType': 'text',
    'content': 'Meeting starts in 10 minutes!',
    'localId': '550e8400-e29b-41d4-a716-446655440003',
  }),
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "665d4c5e6f7a8b9c0d1e2f3b",
    "sId": "665a1f2e3b4c5d6e7f8a9b0c",
    "sName": "John Doe",
    "sImg": "https://cdn.weellu.com/users/665a1f2e3b4c5d6e7f8a9b0c_thumb.png",
    "plm": "Web",
    "rId": "665b2a3c4d5e6f7a8b9c0d1e",
    "c": "Meeting starts in 10 minutes!",
    "mT": "text",
    "lId": "550e8400-e29b-41d4-a716-446655440003",
    "mentions": [],
    "mentionAll": false,
    "createdAt": "2026-03-18T14:35:00.000Z"
  }
}

Get Messages

GET https://api.weellu.com/api/v1/channel/:roomId/message/

Retrieves messages from a room with filtering and pagination support. Supports directional cursor-based pagination using before and after parameters.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room (path parameter)
limit string (number) No Number of messages to return (default: 20)
filter string No Filter messages by content type
before string No MongoDB ObjectId; return messages older than this message (cursor-based pagination backward)
after string No MongoDB ObjectId; return messages newer than this message (cursor-based pagination forward)
text string No Full-text search on message content
fromDate string (ISO 8601) No Start date for date range filter (requires toDate)
toDate string (ISO 8601) No End date for date range filter (requires fromDate)
parentId string No MongoDB ObjectId; filter messages by parent task ID (for task sub-messages)
page string (number) No Page number for offset-based pagination
lastId string No MongoDB ObjectId for cursor-based pagination (deprecated, use before)

MessageFilter Enum (filter)

Value Description
all All message types (default)
media Images and videos only
links Messages containing links
file File attachments only
voice Voice messages only

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/?limit=30&filter=all" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/?limit=30&filter=all",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/?limit=30&filter=all'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Request (cursor-based pagination)

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/?limit=20&before=665d4c5e6f7a8b9c0d1e2f3a" \
  -H "Authorization: Bearer TOKEN"

Example Request (date range + text search)

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/?fromDate=2026-03-01T00:00:00.000Z&toDate=2026-03-18T23:59:59.999Z&text=payment" \
  -H "Authorization: Bearer TOKEN"

Example Request (task sub-messages)

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/?parentId=665d4c5e6f7a8b9c0d1e2f3a&limit=50" \
  -H "Authorization: Bearer TOKEN"

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "665d4c5e6f7a8b9c0d1e2f3b",
      "sId": "665a1f2e3b4c5d6e7f8a9b0c",
      "sName": "John Doe",
      "sImg": "https://cdn.weellu.com/users/665a1f2e3b4c5d6e7f8a9b0c_thumb.png",
      "plm": "Android",
      "rId": "665b2a3c4d5e6f7a8b9c0d1e",
      "c": "Hello team!",
      "mT": "text",
      "msgAtt": null,
      "rTo": null,
      "lId": "550e8400-e29b-41d4-a716-446655440000",
      "mentions": [],
      "mentionAll": false,
      "stars": [],
      "reactions": [],
      "isEdited": false,
      "pinnedAt": null,
      "parentId": null,
      "createdAt": "2026-03-18T14:30:00.000Z",
      "updatedAt": "2026-03-18T14:30:00.000Z"
    },
    {
      "_id": "665d4c5e6f7a8b9c0d1e2f3c",
      "sId": "665a1f2e3b4c5d6e7f8a9b0d",
      "sName": "Jane Smith",
      "sImg": "https://cdn.weellu.com/users/665a1f2e3b4c5d6e7f8a9b0d_thumb.png",
      "plm": "Ios",
      "rId": "665b2a3c4d5e6f7a8b9c0d1e",
      "c": "",
      "mT": "image",
      "msgAtt": {
        "fileSource": "https://cdn.weellu.com/chat/665d4c5e.jpg",
        "width": 1920,
        "height": 1080
      },
      "lId": "550e8400-e29b-41d4-a716-446655440001",
      "mentions": [],
      "stars": [],
      "reactions": [
        { "userId": "665a1f2e3b4c5d6e7f8a9b0c", "reaction": "thumbsup" }
      ],
      "isEdited": false,
      "createdAt": "2026-03-18T14:31:00.000Z",
      "updatedAt": "2026-03-18T14:32:00.000Z"
    }
  ]
}

Delete Message

DELETE https://api.weellu.com/api/v1/channel/:roomId/message/:messageId/delete/:type

Deletes a message. Can delete for everyone or only for the current user.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room (path parameter)
messageId string Yes MongoDB ObjectId of the message (path parameter)
type string Yes Deletion scope (path parameter)

DeleteMessageType Enum (type)

Value Description
all Delete for all participants (sender only, within time window)
me Delete only for the current user (hide from own view)

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/delete/all" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/delete/all",
  { method: "DELETE", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.delete(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/delete/all'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Add Reaction

PATCH https://api.weellu.com/api/v1/channel/:roomId/message/:messageId/reaction

Adds or updates a reaction on a message. Each user can have one reaction per message; sending a new reaction replaces the previous one.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room (path parameter)
messageId string Yes MongoDB ObjectId of the message (path parameter)
reaction string Yes Reaction emoji identifier (e.g. thumbsup, heart, fire) (body)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/reaction" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"reaction": "thumbsup"}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/reaction",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ reaction: "thumbsup" })
  }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/reaction'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({'reaction': 'thumbsup'}),
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Remove Reaction

DELETE https://api.weellu.com/api/v1/channel/:roomId/message/:messageId/reaction

Removes the current user's reaction from a message.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room (path parameter)
messageId string Yes MongoDB ObjectId of the message (path parameter)

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/reaction" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/reaction",
  { method: "DELETE", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.delete(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/reaction'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Get Reactions

GET https://api.weellu.com/api/v1/channel/:roomId/message/:messageId/reactions

Retrieves all reactions on a specific message with user details.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room (path parameter)
messageId string Yes MongoDB ObjectId of the message (path parameter)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/reactions" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/reactions",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/reactions'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": [
    {
      "userId": "665a1f2e3b4c5d6e7f8a9b0c",
      "reaction": "thumbsup"
    },
    {
      "userId": "665a1f2e3b4c5d6e7f8a9b0d",
      "reaction": "heart"
    }
  ]
}

Star Message

POST https://api.weellu.com/api/v1/channel/:roomId/message/:messageId/star

Stars (bookmarks) a message for the current user.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room (path parameter)
messageId string Yes MongoDB ObjectId of the message to star (path parameter)

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/star" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/star",
  { method: "POST", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.post(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/star'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Un-star Message

POST https://api.weellu.com/api/v1/channel/:roomId/message/:messageId/un-star

Removes a star (bookmark) from a message for the current user.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room (path parameter)
messageId string Yes MongoDB ObjectId of the message to un-star (path parameter)

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/un-star" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/un-star",
  { method: "POST", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.post(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/un-star'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Get Room Starred Messages

GET https://api.weellu.com/api/v1/channel/:roomId/message/stars

Retrieves all starred (bookmarked) messages for the current user within a specific room.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room (path parameter)
page string (number) No Page number (default: 1)
limit string (number) No Items per page (default: 20)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/stars?page=1&limit=20" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/stars?page=1&limit=20",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/stars?page=1&limit=20'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "665d4c5e6f7a8b9c0d1e2f3a",
      "sId": "665a1f2e3b4c5d6e7f8a9b0c",
      "sName": "John Doe",
      "sImg": "https://cdn.weellu.com/users/665a1f2e3b4c5d6e7f8a9b0c_thumb.png",
      "rId": "665b2a3c4d5e6f7a8b9c0d1e",
      "c": "Important message to remember",
      "mT": "text",
      "createdAt": "2026-03-15T09:30:00.000Z"
    }
  ]
}

Pin Message

PATCH https://api.weellu.com/api/v1/channel/:roomId/message/:messageId/pin

Pins a message in the room. Works for all room types including projects.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room (path parameter)
messageId string Yes MongoDB ObjectId of the message to pin (path parameter)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/pin" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/pin",
  { method: "PATCH", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/pin'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Pin Message (v2 with Expiry)

PATCH https://api.weellu.com/api/v1/channel/:roomId/message/:messageId/pin/v2

Pins a message with an optional expiry date. Works for all room types including projects.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room (path parameter)
messageId string Yes MongoDB ObjectId of the message to pin (path parameter)
date string (ISO 8601) Yes Expiry date for the pin (body)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/pin/v2" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"date": "2026-04-18T23:59:59.000Z"}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/pin/v2",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ date: "2026-04-18T23:59:59.000Z" })
  }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/pin/v2'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({'date': '2026-04-18T23:59:59.000Z'}),
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Un-pin Message

PATCH https://api.weellu.com/api/v1/channel/:roomId/message/:messageId/un-pin

Removes a pin from a message. Works for all room types including projects.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room (path parameter)
messageId string Yes MongoDB ObjectId of the message to un-pin (path parameter)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/un-pin" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/un-pin",
  { method: "PATCH", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/un-pin'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Get Pinned Messages (v2)

GET https://api.weellu.com/api/v1/channel/:roomId/message/pin/v2

Retrieves all currently pinned messages in a room. Optionally filter by parent task ID.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room (path parameter)
parentTaskId string No MongoDB ObjectId of a parent task to scope pinned messages (query parameter)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/pin/v2" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/pin/v2",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/pin/v2'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Request (filtered by parent task)

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/pin/v2?parentTaskId=665d4c5e6f7a8b9c0d1e2f3a" \
  -H "Authorization: Bearer TOKEN"

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "665d4c5e6f7a8b9c0d1e2f3a",
      "sId": "665a1f2e3b4c5d6e7f8a9b0c",
      "sName": "John Doe",
      "rId": "665b2a3c4d5e6f7a8b9c0d1e",
      "c": "Sprint goals for this week",
      "mT": "text",
      "pinnedAt": "2026-03-18T10:00:00.000Z",
      "pinnedTo": "2026-04-18T23:59:59.000Z",
      "createdAt": "2026-03-17T09:00:00.000Z"
    }
  ]
}

Voice Transcription

GET https://api.weellu.com/api/v1/channel/:roomId/message/:messageId/transcribe

Transcribes a voice message to text using AI.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room (path parameter)
messageId string Yes MongoDB ObjectId of the voice message (path parameter)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/transcribe" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/transcribe",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/transcribe'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": {
    "text": "Hey team, just wanted to remind everyone about the standup meeting at 10am tomorrow. Please prepare your updates."
  }
}

Convert to MP3

POST https://api.weellu.com/api/v1/channel/:roomId/message/:messageId/convert-to-mp3

Converts a voice message to MP3 format.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the room (path parameter)
messageId string Yes MongoDB ObjectId of the voice message (path parameter)

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/convert-to-mp3" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/convert-to-mp3",
  { method: "POST", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.post(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/message/665d4c5e6f7a8b9c0d1e2f3a/convert-to-mp3'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": {
    "url": "https://cdn.weellu.com/chat/665d4c5e6f7a8b9c0d1e2f3a.mp3"
  }
}

Tasks

Task endpoints manage tasks within project channels. Tasks are a special message type (mT: "task") with structured metadata in msgAtt. All endpoints require authentication via Authorization: Bearer TOKEN.

Base URL: https://api.weellu.com/api/v1/channel

Update Task

PATCH https://api.weellu.com/api/v1/channel/:roomId/task/:taskId

Updates one or more fields of a task. All body fields are optional -- send only the fields you want to change.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
taskId string Yes MongoDB ObjectId of the task message (path parameter)
status string No New task status (body)
flag string No New task priority flag (body)
title string No New task title (body)
desc string No New task description (body)
added object[] No Array of user objects to add as designations (body). Each object must contain an _id field with a valid MongoDB ObjectId
deleted object[] No Array of user objects to remove from designations (body). Each object must contain an _id field with a valid MongoDB ObjectId
isAllDesignation boolean No If true, designate all project members (body)
categoryId string No MongoDB ObjectId of the task category (body)
location string No Location string for the task (body)

TaskStatus Enum (status)

Value Description
open Newly created task
reOpen Reopened after completion
onProgress Work in progress
done Completed
revision Under review
canceled Cancelled
concluded Finalized/concluded
reopenRejected Reopen request was rejected
reScheduled Rescheduled for later

TaskFlag Enum (flag)

Value Description
urgent Urgent priority
veryHigh Very high priority
high High priority
normal Normal priority
low Low priority

Example Request (update status and flag)

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "onProgress",
    "flag": "high"
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      status: "onProgress",
      flag: "high"
    })
  }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({'status': 'onProgress', 'flag': 'high'}),
);

Example Request (update designations)

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "added": [{"_id": "665a1f2e3b4c5d6e7f8a9b0e"}],
    "deleted": [{"_id": "665a1f2e3b4c5d6e7f8a9b0f"}],
    "categoryId": "665c3b4d5e6f7a8b9c0d1e2f"
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      added: [{ _id: "665a1f2e3b4c5d6e7f8a9b0e" }],
      deleted: [{ _id: "665a1f2e3b4c5d6e7f8a9b0f" }],
      categoryId: "665c3b4d5e6f7a8b9c0d1e2f"
    })
  }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({
    'added': [{'_id': '665a1f2e3b4c5d6e7f8a9b0e'}],
    'deleted': [{'_id': '665a1f2e3b4c5d6e7f8a9b0f'}],
    'categoryId': '665c3b4d5e6f7a8b9c0d1e2f',
  }),
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Transfer Task

PATCH https://api.weellu.com/api/v1/channel/:roomId/task/:taskId/transfer

Transfers a task to a different project, optionally updating the designation list.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the current project room (path parameter)
taskId string Yes MongoDB ObjectId of the task message (path parameter)
toProject string Yes MongoDB ObjectId of the destination project room (body)
designations object[] Yes Array of user objects for designation in the new project. Can be empty array (body). Each object must contain an _id field with a valid MongoDB ObjectId

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/transfer" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "toProject": "665b2a3c4d5e6f7a8b9c0d2f",
    "designations": [
      {"_id": "665a1f2e3b4c5d6e7f8a9b0c"},
      {"_id": "665a1f2e3b4c5d6e7f8a9b0d"}
    ]
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/transfer",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      toProject: "665b2a3c4d5e6f7a8b9c0d2f",
      designations: [
        { _id: "665a1f2e3b4c5d6e7f8a9b0c" },
        { _id: "665a1f2e3b4c5d6e7f8a9b0d" }
      ]
    })
  }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/transfer'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({
    'toProject': '665b2a3c4d5e6f7a8b9c0d2f',
    'designations': [
      {'_id': '665a1f2e3b4c5d6e7f8a9b0c'},
      {'_id': '665a1f2e3b4c5d6e7f8a9b0d'},
    ],
  }),
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Open Task

PATCH https://api.weellu.com/api/v1/channel/:roomId/task/:taskId/open

Marks a task as opened/viewed by the current user. Used for tracking who has acknowledged the task.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
taskId string Yes MongoDB ObjectId of the task message (path parameter)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/open" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/open",
  { method: "PATCH", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/open'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Check Open Task

GET https://api.weellu.com/api/v1/channel/:roomId/task/:taskId/open-check

Checks whether the current user has opened/viewed a specific task.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
taskId string Yes MongoDB ObjectId of the task message (path parameter)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/open-check" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/open-check",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/open-check'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": {
    "opened": true,
    "openedAt": "2026-03-18T14:30:00.000Z"
  }
}

Get Task Designation (v2)

GET https://api.weellu.com/api/v1/channel/:roomId/task/:taskId/designation/v2

Retrieves the list of users designated (assigned) to a task with their details.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
taskId string Yes MongoDB ObjectId of the task message (path parameter)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/designation/v2" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/designation/v2",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/designation/v2'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "665a1f2e3b4c5d6e7f8a9b0c",
      "fullName": "John Doe",
      "userImage": "https://cdn.weellu.com/users/665a1f2e3b4c5d6e7f8a9b0c.png",
      "username": "johndoe"
    },
    {
      "_id": "665a1f2e3b4c5d6e7f8a9b0d",
      "fullName": "Jane Smith",
      "userImage": "https://cdn.weellu.com/users/665a1f2e3b4c5d6e7f8a9b0d.png",
      "username": "janesmith"
    }
  ]
}

Get Task Activity Logs

GET https://api.weellu.com/api/v1/channel/:roomId/task/:taskId/activity-logs

Retrieves the activity log for a specific task with pagination. Includes status changes, designation updates, flag changes, etc.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
taskId string Yes MongoDB ObjectId of the task message (path parameter)
page string (number) No Page number (default: 1)
limit string (number) No Items per page (default: 20)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/activity-logs?page=1&limit=20" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/activity-logs?page=1&limit=20",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/activity-logs?page=1&limit=20'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": {
    "docs": [
      {
        "_id": "665e5d6f7a8b9c0d1e2f3a4b",
        "action": "updateTaskStatus",
        "userId": "665a1f2e3b4c5d6e7f8a9b0c",
        "userName": "John Doe",
        "details": {
          "oldStatus": "open",
          "newStatus": "onProgress"
        },
        "createdAt": "2026-03-18T14:00:00.000Z"
      },
      {
        "_id": "665e5d6f7a8b9c0d1e2f3a4c",
        "action": "addTaskDesignation",
        "userId": "665a1f2e3b4c5d6e7f8a9b0c",
        "userName": "John Doe",
        "details": {
          "addedUser": "Jane Smith"
        },
        "createdAt": "2026-03-18T13:50:00.000Z"
      }
    ],
    "totalDocs": 8,
    "limit": 20,
    "page": 1,
    "totalPages": 1
  }
}

Get Task Message Status

GET https://api.weellu.com/api/v1/channel/:roomId/task/message/:messageId/status/:type

Retrieves delivery or read status for a task message, showing which users have seen or received it.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
messageId string Yes MongoDB ObjectId of the task message (path parameter)
type string Yes Status type to query (path parameter)
page string (number) No Page number (default: 1)
limit string (number) No Items per page (default: 20)

MessageStatusType Enum (type)

Value Description
seen Users who have read the message
deliver Users who have received the message

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/message/665d4c5e6f7a8b9c0d1e2f3a/status/seen?page=1&limit=20" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/message/665d4c5e6f7a8b9c0d1e2f3a/status/seen?page=1&limit=20",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/message/665d4c5e6f7a8b9c0d1e2f3a/status/seen?page=1&limit=20'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": {
    "docs": [
      {
        "_id": "665a1f2e3b4c5d6e7f8a9b0c",
        "fullName": "John Doe",
        "userImage": "https://cdn.weellu.com/users/665a1f2e3b4c5d6e7f8a9b0c.png",
        "seenAt": "2026-03-18T14:35:00.000Z"
      },
      {
        "_id": "665a1f2e3b4c5d6e7f8a9b0d",
        "fullName": "Jane Smith",
        "userImage": "https://cdn.weellu.com/users/665a1f2e3b4c5d6e7f8a9b0d.png",
        "seenAt": "2026-03-18T14:40:00.000Z"
      }
    ],
    "totalDocs": 2,
    "limit": 20,
    "page": 1,
    "totalPages": 1
  }
}

Update Task IXC Service Order

PATCH https://api.weellu.com/api/v1/channel/:roomId/task/:taskId/ixc-service-order

Links an IXC service order to a task. Requires IXC integration to be enabled on the project.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
taskId string Yes MongoDB ObjectId of the task message (path parameter)
ixcServiceOrder string Yes IXC service order identifier (body)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/ixc-service-order" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"ixcServiceOrder": "OS-2026-00451"}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/ixc-service-order",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ ixcServiceOrder: "OS-2026-00451" })
  }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/ixc-service-order'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({'ixcServiceOrder': 'OS-2026-00451'}),
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Update Task Location

PATCH https://api.weellu.com/api/v1/channel/:roomId/task/:taskId/location

Updates the location associated with a task.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
taskId string Yes MongoDB ObjectId of the task message (path parameter)
location string Yes Location string (e.g. address or coordinates) (body)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/location" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"location": "-23.5505,-46.6333"}'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/location",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ location: "-23.5505,-46.6333" })
  }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/location'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({'location': '-23.5505,-46.6333'}),
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Reminders

Reminder endpoints manage scheduled notifications for tasks within project channels. Reminders are created against a specific task and notify targeted users at calculated intervals. All endpoints require authentication via Authorization: Bearer TOKEN.

Base URL: https://api.weellu.com/api/v1/channel/:roomId/task/:taskId/reminder

Create Reminder

POST https://api.weellu.com/api/v1/channel/:roomId/task/:taskId/reminder

Creates a new reminder for a task. The reminder will notify the specified users after the given number of minutes.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
taskId string Yes MongoDB ObjectId of the task message (path parameter)
targetUserIds string[] Yes Array of user MongoDB ObjectIds to notify. Minimum 1, maximum 50 (body)
minutes number Yes Minutes from now to trigger the reminder. Minimum 1, maximum 525600 (1 year) (body)
customMessage string No Custom notification message. Maximum 500 characters (body)

Constraints

Example Request

curl -X POST "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/reminder" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "targetUserIds": [
      "665a1f2e3b4c5d6e7f8a9b0c",
      "665a1f2e3b4c5d6e7f8a9b0d"
    ],
    "minutes": 60,
    "customMessage": "Please update the task status before end of day."
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/reminder",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      targetUserIds: [
        "665a1f2e3b4c5d6e7f8a9b0c",
        "665a1f2e3b4c5d6e7f8a9b0d"
      ],
      minutes: 60,
      customMessage: "Please update the task status before end of day."
    })
  }
);
const data = await response.json();
final response = await http.post(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/reminder'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({
    'targetUserIds': [
      '665a1f2e3b4c5d6e7f8a9b0c',
      '665a1f2e3b4c5d6e7f8a9b0d',
    ],
    'minutes': 60,
    'customMessage': 'Please update the task status before end of day.',
  }),
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "665f8a9b0c1d2e3f4a5b6c7d",
    "taskId": "665d4c5e6f7a8b9c0d1e2f3a",
    "roomId": "665b2a3c4d5e6f7a8b9c0d1e",
    "creatorId": "665a1f2e3b4c5d6e7f8a9b0c",
    "targetUserIds": [
      "665a1f2e3b4c5d6e7f8a9b0c",
      "665a1f2e3b4c5d6e7f8a9b0d"
    ],
    "alerts": [
      {
        "_id": "665f8a9b0c1d2e3f4a5b6c7e",
        "scheduledAt": "2026-03-18T15:30:00.000Z",
        "status": "pending"
      }
    ],
    "status": "active",
    "customMessage": "Please update the task status before end of day.",
    "createdAt": "2026-03-18T14:30:00.000Z",
    "updatedAt": "2026-03-18T14:30:00.000Z"
  }
}

List Reminders

GET https://api.weellu.com/api/v1/channel/:roomId/task/:taskId/reminder

Retrieves all reminders for a specific task.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
taskId string Yes MongoDB ObjectId of the task message (path parameter)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/reminder" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/reminder",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/reminder'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "665f8a9b0c1d2e3f4a5b6c7d",
      "taskId": "665d4c5e6f7a8b9c0d1e2f3a",
      "roomId": "665b2a3c4d5e6f7a8b9c0d1e",
      "creatorId": "665a1f2e3b4c5d6e7f8a9b0c",
      "targetUserIds": [
        "665a1f2e3b4c5d6e7f8a9b0c",
        "665a1f2e3b4c5d6e7f8a9b0d"
      ],
      "alerts": [
        {
          "_id": "665f8a9b0c1d2e3f4a5b6c7e",
          "scheduledAt": "2026-03-18T15:30:00.000Z",
          "status": "pending"
        }
      ],
      "status": "active",
      "customMessage": "Please update the task status before end of day.",
      "createdAt": "2026-03-18T14:30:00.000Z",
      "updatedAt": "2026-03-18T14:30:00.000Z"
    }
  ]
}

Get Reminder

GET https://api.weellu.com/api/v1/channel/:roomId/task/:taskId/reminder/:reminderId

Retrieves a single reminder by its ID.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
taskId string Yes MongoDB ObjectId of the task message (path parameter)
reminderId string Yes MongoDB ObjectId of the reminder (path parameter)

Example Request

curl -X GET "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/reminder/665f8a9b0c1d2e3f4a5b6c7d" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/reminder/665f8a9b0c1d2e3f4a5b6c7d",
  { headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.get(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/reminder/665f8a9b0c1d2e3f4a5b6c7d'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "665f8a9b0c1d2e3f4a5b6c7d",
    "taskId": "665d4c5e6f7a8b9c0d1e2f3a",
    "roomId": "665b2a3c4d5e6f7a8b9c0d1e",
    "creatorId": "665a1f2e3b4c5d6e7f8a9b0c",
    "targetUserIds": [
      "665a1f2e3b4c5d6e7f8a9b0c",
      "665a1f2e3b4c5d6e7f8a9b0d"
    ],
    "alerts": [
      {
        "_id": "665f8a9b0c1d2e3f4a5b6c7e",
        "scheduledAt": "2026-03-18T15:30:00.000Z",
        "status": "sent"
      }
    ],
    "status": "completed",
    "customMessage": "Please update the task status before end of day.",
    "createdAt": "2026-03-18T14:30:00.000Z",
    "updatedAt": "2026-03-18T15:30:05.000Z"
  }
}

ReminderStatus Enum

Value Description
active Reminder is scheduled and has pending alerts
cancelled Reminder was cancelled before completion
completed All alerts have been sent

AlertStatus Enum

Value Description
pending Alert is scheduled but not yet sent
sent Alert notification has been delivered
cancelled Alert was cancelled

Update Reminder

PATCH https://api.weellu.com/api/v1/channel/:roomId/task/:taskId/reminder/:reminderId

Updates an existing reminder. You can change the target users and/or the timing.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
taskId string Yes MongoDB ObjectId of the task message (path parameter)
reminderId string Yes MongoDB ObjectId of the reminder (path parameter)
targetUserIds string[] No Updated array of user IDs. Minimum 1, maximum 50 (body)
minutes number No Updated minutes from now. Minimum 1, maximum 525600 (body)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/reminder/665f8a9b0c1d2e3f4a5b6c7d" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "targetUserIds": [
      "665a1f2e3b4c5d6e7f8a9b0c",
      "665a1f2e3b4c5d6e7f8a9b0d",
      "665a1f2e3b4c5d6e7f8a9b0e"
    ],
    "minutes": 120
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/reminder/665f8a9b0c1d2e3f4a5b6c7d",
  {
    method: "PATCH",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      targetUserIds: [
        "665a1f2e3b4c5d6e7f8a9b0c",
        "665a1f2e3b4c5d6e7f8a9b0d",
        "665a1f2e3b4c5d6e7f8a9b0e"
      ],
      minutes: 120
    })
  }
);
const data = await response.json();
final response = await http.patch(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/reminder/665f8a9b0c1d2e3f4a5b6c7d'),
  headers: {'Authorization': 'Bearer TOKEN', 'Content-Type': 'application/json'},
  body: jsonEncode({
    'targetUserIds': [
      '665a1f2e3b4c5d6e7f8a9b0c',
      '665a1f2e3b4c5d6e7f8a9b0d',
      '665a1f2e3b4c5d6e7f8a9b0e',
    ],
    'minutes': 120,
  }),
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "665f8a9b0c1d2e3f4a5b6c7d",
    "taskId": "665d4c5e6f7a8b9c0d1e2f3a",
    "roomId": "665b2a3c4d5e6f7a8b9c0d1e",
    "creatorId": "665a1f2e3b4c5d6e7f8a9b0c",
    "targetUserIds": [
      "665a1f2e3b4c5d6e7f8a9b0c",
      "665a1f2e3b4c5d6e7f8a9b0d",
      "665a1f2e3b4c5d6e7f8a9b0e"
    ],
    "alerts": [
      {
        "_id": "665f8a9b0c1d2e3f4a5b6c80",
        "scheduledAt": "2026-03-18T16:30:00.000Z",
        "status": "pending"
      }
    ],
    "status": "active",
    "customMessage": "Please update the task status before end of day.",
    "createdAt": "2026-03-18T14:30:00.000Z",
    "updatedAt": "2026-03-18T14:35:00.000Z"
  }
}

Delete Reminder

DELETE https://api.weellu.com/api/v1/channel/:roomId/task/:taskId/reminder/:reminderId

Deletes a reminder and cancels any pending alerts.

Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the project room (path parameter)
taskId string Yes MongoDB ObjectId of the task message (path parameter)
reminderId string Yes MongoDB ObjectId of the reminder (path parameter)

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/reminder/665f8a9b0c1d2e3f4a5b6c7d" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/reminder/665f8a9b0c1d2e3f4a5b6c7d",
  { method: "DELETE", headers: { "Authorization": "Bearer TOKEN" } }
);
const data = await response.json();
final response = await http.delete(
  Uri.parse('https://api.weellu.com/api/v1/channel/665b2a3c4d5e6f7a8b9c0d1e/task/665d4c5e6f7a8b9c0d1e2f3a/reminder/665f8a9b0c1d2e3f4a5b6c7d'),
  headers: {'Authorization': 'Bearer TOKEN'},
);

Example Response

{
  "code": 200,
  "data": "Done"
}

Calls

The Calls API provides voice and video calling capabilities powered by Agora and WebRTC. All endpoints require authentication.

Enums

CallStatus

Value Description
ring Call is currently ringing
canceled Call was canceled by the caller
timeout Call timed out (no answer)
offline Callee was offline
rejected Call was rejected by the callee
finished Call ended normally
serverRestart Call ended due to server restart
inCall Call is currently active

MeetPlatform

Value Description
webRtc Peer-to-peer WebRTC calling
agora Agora cloud-based calling (recommended for group calls)

Create Call

POST https://api.weellu.com/api/v1/call/create/:roomId

Initiates a new voice or video call in the specified room. The server will ring all participants in the room and send push notifications to offline users.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the chat room

Body Parameters

Parameter Type Required Description
withVideo boolean Yes true for video call, false for voice-only call
meetPlatform string Yes Platform to use: webRtc or agora
payload any No Arbitrary JSON payload passed to callees (e.g., SDP offer for WebRTC)

Example Request

curl -X POST "https://api.weellu.com/api/v1/call/create/665a1f3b2e4c8a001d3b7f01" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "withVideo": true,
    "meetPlatform": "agora",
    "payload": {"sdp": "offer-data"}
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/call/create/665a1f3b2e4c8a001d3b7f01",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      withVideo: true,
      meetPlatform: "agora",
      payload: { sdp: "offer-data" },
    }),
  }
);
const data = await response.json();
import 'package:chopper/chopper.dart';

final response = await apiService.post(
  '/call/create/665a1f3b2e4c8a001d3b7f01',
  body: {
    'withVideo': true,
    'meetPlatform': 'agora',
    'payload': {'sdp': 'offer-data'},
  },
);

Example Response

{
  "data": {
    "_id": "665a2b8c4f1e9a002a4c8d12",
    "caller": "665a1a2b3c4d5e006f7a8b01",
    "participants": [
      "665a1a2b3c4d5e006f7a8b01"
    ],
    "callee": "665a1a2b3c4d5e006f7a8b02",
    "callStatus": "ring",
    "roomId": "665a1f3b2e4c8a001d3b7f01",
    "roomType": "s",
    "withVideo": true,
    "meetPlatform": "agora",
    "endAt": null,
    "createdAt": "2026-03-18T10:30:00.000Z"
  }
}

Get Active Ringing Call

GET https://api.weellu.com/api/v1/call/active

Returns the currently active ringing call for the authenticated user, if any. Useful on app startup to check if a call is in progress.

Parameters

No parameters required.

Example Request

curl -X GET "https://api.weellu.com/api/v1/call/active" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch("https://api.weellu.com/api/v1/call/active", {
  headers: { "Authorization": "Bearer TOKEN" },
});
const data = await response.json();
final response = await apiService.get('/call/active');

Example Response (active call exists)

{
  "data": {
    "_id": "665a2b8c4f1e9a002a4c8d12",
    "caller": "665a1a2b3c4d5e006f7a8b01",
    "participants": [
      "665a1a2b3c4d5e006f7a8b01"
    ],
    "callee": "665a1a2b3c4d5e006f7a8b02",
    "callStatus": "ring",
    "roomId": "665a1f3b2e4c8a001d3b7f01",
    "roomType": "s",
    "withVideo": false,
    "meetPlatform": "webRtc",
    "endAt": null,
    "createdAt": "2026-03-18T10:30:00.000Z"
  }
}

Example Response (no active call)

{
  "data": null
}

Get Agora Access Token

GET https://api.weellu.com/api/v1/call/agora-access/:roomId

Generates a temporary Agora RTC token for the authenticated user to join the call channel. The token is scoped to the specific room and expires after a set duration.

Path Parameters

Parameter Type Required Description
roomId string Yes MongoDB ObjectId of the chat room with an active Agora call

Example Request

curl -X GET "https://api.weellu.com/api/v1/call/agora-access/665a1f3b2e4c8a001d3b7f01" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/call/agora-access/665a1f3b2e4c8a001d3b7f01",
  {
    headers: { "Authorization": "Bearer TOKEN" },
  }
);
const data = await response.json();
final response = await apiService.get(
  '/call/agora-access/665a1f3b2e4c8a001d3b7f01',
);

Example Response

{
  "data": {
    "token": "006a1b2c3d4e5f...agoraRtcToken",
    "agoraUid": 123456789,
    "channelName": "665a1f3b2e4c8a001d3b7f01"
  }
}

Accept Call

POST https://api.weellu.com/api/v1/call/accept/:callId

Accepts an incoming call. This notifies the caller that the call has been accepted and transitions the call status to inCall.

Path Parameters

Parameter Type Required Description
callId string Yes MongoDB ObjectId of the call to accept

Body Parameters

Parameter Type Required Description
payload any No Arbitrary JSON payload sent to the caller (e.g., SDP answer for WebRTC)

Example Request

curl -X POST "https://api.weellu.com/api/v1/call/accept/665a2b8c4f1e9a002a4c8d12" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "payload": {"sdp": "answer-data"}
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/call/accept/665a2b8c4f1e9a002a4c8d12",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      payload: { sdp: "answer-data" },
    }),
  }
);
const data = await response.json();
final response = await apiService.post(
  '/call/accept/665a2b8c4f1e9a002a4c8d12',
  body: {
    'payload': {'sdp': 'answer-data'},
  },
);

Example Response

{
  "data": {
    "_id": "665a2b8c4f1e9a002a4c8d12",
    "callStatus": "inCall",
    "roomId": "665a1f3b2e4c8a001d3b7f01",
    "withVideo": true,
    "meetPlatform": "agora"
  }
}

Invite Users to Call

POST https://api.weellu.com/api/v1/call/invite/:callId

Invites additional users to an ongoing call. Only works for group or project rooms. Each invited user will receive a push notification and ring event.

Path Parameters

Parameter Type Required Description
callId string Yes MongoDB ObjectId of the active call

Body Parameters

Parameter Type Required Description
userIds string[] Yes Array of MongoDB ObjectId strings of users to invite. Must be non-empty. Each element must be a valid string.

Example Request

curl -X POST "https://api.weellu.com/api/v1/call/invite/665a2b8c4f1e9a002a4c8d12" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "userIds": [
      "665a1a2b3c4d5e006f7a8b03",
      "665a1a2b3c4d5e006f7a8b04"
    ]
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/call/invite/665a2b8c4f1e9a002a4c8d12",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      userIds: [
        "665a1a2b3c4d5e006f7a8b03",
        "665a1a2b3c4d5e006f7a8b04",
      ],
    }),
  }
);
const data = await response.json();
final response = await apiService.post(
  '/call/invite/665a2b8c4f1e9a002a4c8d12',
  body: {
    'userIds': [
      '665a1a2b3c4d5e006f7a8b03',
      '665a1a2b3c4d5e006f7a8b04',
    ],
  },
);

Example Response

{
  "data": true
}

End Call

POST https://api.weellu.com/api/v1/call/end/v2/:callId

Ends an active call. Can be called by any participant. If the call is still ringing, this cancels it. If in progress, this finishes it. The server broadcasts the end event to all participants via Socket.IO.

Path Parameters

Parameter Type Required Description
callId string Yes MongoDB ObjectId of the call to end

Body Parameters

Parameter Type Required Description
endAt string No ISO 8601 datetime string marking when the call ended. If omitted, the server uses the current time. Must be a valid ISO 8601 date (e.g., 2026-03-18T10:45:00.000Z).

Example Request

curl -X POST "https://api.weellu.com/api/v1/call/end/v2/665a2b8c4f1e9a002a4c8d12" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "endAt": "2026-03-18T10:45:00.000Z"
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/call/end/v2/665a2b8c4f1e9a002a4c8d12",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      endAt: "2026-03-18T10:45:00.000Z",
    }),
  }
);
const data = await response.json();
final response = await apiService.post(
  '/call/end/v2/665a2b8c4f1e9a002a4c8d12',
  body: {
    'endAt': '2026-03-18T10:45:00.000Z',
  },
);

Example Response

{
  "data": {
    "_id": "665a2b8c4f1e9a002a4c8d12",
    "callStatus": "finished",
    "endAt": "2026-03-18T10:45:00.000Z"
  }
}

Get Call Participants

GET https://api.weellu.com/api/v1/call/participants/:callId

Returns the list of participants currently in the specified call with their Agora UIDs and profile information.

Path Parameters

Parameter Type Required Description
callId string Yes MongoDB ObjectId of the call

Example Request

curl -X GET "https://api.weellu.com/api/v1/call/participants/665a2b8c4f1e9a002a4c8d12" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/call/participants/665a2b8c4f1e9a002a4c8d12",
  {
    headers: { "Authorization": "Bearer TOKEN" },
  }
);
const data = await response.json();
final response = await apiService.get(
  '/call/participants/665a2b8c4f1e9a002a4c8d12',
);

Example Response

{
  "data": [
    {
      "agoraUid": 123456789,
      "odooId": "665a1a2b3c4d5e006f7a8b01",
      "name": "John Doe",
      "image": "https://cdn.weellu.com/pic100/avatar1.jpg",
      "withVideo": true,
      "roomId": "665a1f3b2e4c8a001d3b7f01",
      "callId": "665a2b8c4f1e9a002a4c8d12"
    },
    {
      "agoraUid": 987654321,
      "odooId": "665a1a2b3c4d5e006f7a8b02",
      "name": "Jane Smith",
      "image": "https://cdn.weellu.com/pic100/avatar2.jpg",
      "withVideo": false,
      "roomId": "665a1f3b2e4c8a001d3b7f01",
      "callId": "665a2b8c4f1e9a002a4c8d12"
    }
  ]
}

Get Call History

GET https://api.weellu.com/api/v1/call/history

Returns the paginated call history for the authenticated user, sorted by most recent. Each entry includes call status, duration, participants, and whether it was a video call.

Query Parameters

Parameter Type Required Description
page number No Page number, starting from 1. Defaults to 1.
limit number No Number of results per page. Defaults to 30. Max 100. Values outside 1-100 are clamped to 30.

Example Request

curl -X GET "https://api.weellu.com/api/v1/call/history?page=1&limit=20" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/call/history?page=1&limit=20",
  {
    headers: { "Authorization": "Bearer TOKEN" },
  }
);
const data = await response.json();
final response = await apiService.get(
  '/call/history',
  parameters: {'page': '1', 'limit': '20'},
);

Example Response

{
  "data": {
    "docs": [
      {
        "_id": "665a2b8c4f1e9a002a4c8d12",
        "caller": {
          "_id": "665a1a2b3c4d5e006f7a8b01",
          "fullName": "John Doe",
          "userImages": {
            "chatImage": "https://cdn.weellu.com/pic100/avatar1.jpg"
          }
        },
        "participants": [
          "665a1a2b3c4d5e006f7a8b01",
          "665a1a2b3c4d5e006f7a8b02"
        ],
        "callee": "665a1a2b3c4d5e006f7a8b02",
        "callStatus": "finished",
        "roomId": "665a1f3b2e4c8a001d3b7f01",
        "roomType": "s",
        "withVideo": true,
        "meetPlatform": "agora",
        "endAt": "2026-03-18T10:45:00.000Z",
        "createdAt": "2026-03-18T10:30:00.000Z"
      },
      {
        "_id": "665a2b8c4f1e9a002a4c8d13",
        "caller": {
          "_id": "665a1a2b3c4d5e006f7a8b03",
          "fullName": "Alice Johnson",
          "userImages": {
            "chatImage": "https://cdn.weellu.com/pic100/avatar3.jpg"
          }
        },
        "participants": [
          "665a1a2b3c4d5e006f7a8b03"
        ],
        "callee": "665a1a2b3c4d5e006f7a8b01",
        "callStatus": "rejected",
        "roomId": "665a1f3b2e4c8a001d3b7f02",
        "roomType": "s",
        "withVideo": false,
        "meetPlatform": "webRtc",
        "endAt": null,
        "createdAt": "2026-03-18T09:15:00.000Z"
      }
    ],
    "totalDocs": 42,
    "limit": 20,
    "page": 1,
    "totalPages": 3,
    "hasNextPage": true,
    "hasPrevPage": false,
    "nextPage": 2,
    "prevPage": null
  }
}

Clear All Call History

DELETE https://api.weellu.com/api/v1/call/history/clear

Clears the entire call history for the authenticated user. This is a soft delete -- the user's ID is added to deleteFrom on each history entry, so other participants can still see their history.

Parameters

No parameters required.

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/call/history/clear" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/call/history/clear",
  {
    method: "DELETE",
    headers: { "Authorization": "Bearer TOKEN" },
  }
);
const data = await response.json();
final response = await apiService.delete('/call/history/clear');

Example Response

{
  "data": true
}

Delete Single History Entry

DELETE https://api.weellu.com/api/v1/call/history/clear/:id

Deletes a single call history entry for the authenticated user. This is a soft delete scoped to the requesting user only.

Path Parameters

Parameter Type Required Description
id string Yes MongoDB ObjectId of the call history entry to delete

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/call/history/clear/665a2b8c4f1e9a002a4c8d12" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/call/history/clear/665a2b8c4f1e9a002a4c8d12",
  {
    method: "DELETE",
    headers: { "Authorization": "Bearer TOKEN" },
  }
);
const data = await response.json();
final response = await apiService.delete(
  '/call/history/clear/665a2b8c4f1e9a002a4c8d12',
);

Example Response

{
  "data": true
}

Social

The Social API covers the follow system and user stories. All endpoints require authentication.

Follow System

The follow system allows users to follow and unfollow each other. The relationship is stored as a followerId / followingId pair with a unique compound index, so duplicate follows are not possible.

Follow / Unfollow Toggle

POST https://api.weellu.com/api/v1/follow/

Toggles the follow state between the authenticated user and the target user. If not following, this creates a follow. If already following, this unfollows. The target user receives a push notification on new follows.

Body Parameters

Parameter Type Required Description
id string Yes MongoDB ObjectId of the target user to follow or unfollow. Must be a valid 24-character hex string.

Example Request

curl -X POST "https://api.weellu.com/api/v1/follow/" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "665a1a2b3c4d5e006f7a8b02"
  }'
const response = await fetch("https://api.weellu.com/api/v1/follow/", {
  method: "POST",
  headers: {
    "Authorization": "Bearer TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    id: "665a1a2b3c4d5e006f7a8b02",
  }),
});
const data = await response.json();
final response = await apiService.post(
  '/follow/',
  body: {
    'id': '665a1a2b3c4d5e006f7a8b02',
  },
);

Example Response (followed)

{
  "data": {
    "_id": "665a3c4d5e6f7a008b9c0d01",
    "followerId": "665a1a2b3c4d5e006f7a8b01",
    "followingId": "665a1a2b3c4d5e006f7a8b02",
    "isEnable": true
  }
}

Example Response (unfollowed)

{
  "data": {
    "_id": "665a3c4d5e6f7a008b9c0d01",
    "followerId": "665a1a2b3c4d5e006f7a8b01",
    "followingId": "665a1a2b3c4d5e006f7a8b02",
    "isEnable": false
  }
}

Get My Followers

GET https://api.weellu.com/api/v1/follow/my-followers

Returns a paginated list of users who follow the authenticated user.

Query Parameters

Parameter Type Required Description
page number No Page number, starting from 1. Defaults to 1.
limit number No Number of results per page. Defaults to 20.

Example Request

curl -X GET "https://api.weellu.com/api/v1/follow/my-followers?page=1&limit=20" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/follow/my-followers?page=1&limit=20",
  {
    headers: { "Authorization": "Bearer TOKEN" },
  }
);
const data = await response.json();
final response = await apiService.get(
  '/follow/my-followers',
  parameters: {'page': '1', 'limit': '20'},
);

Example Response

{
  "data": {
    "docs": [
      {
        "_id": "665a3c4d5e6f7a008b9c0d01",
        "followerId": {
          "_id": "665a1a2b3c4d5e006f7a8b03",
          "fullName": "Alice Johnson",
          "userImages": {
            "chatImage": "https://cdn.weellu.com/pic100/avatar3.jpg",
            "smallImage": "https://cdn.weellu.com/si400/avatar3.jpg"
          },
          "bio": "Flutter developer"
        },
        "followingId": "665a1a2b3c4d5e006f7a8b01",
        "isEnable": true
      },
      {
        "_id": "665a3c4d5e6f7a008b9c0d02",
        "followerId": {
          "_id": "665a1a2b3c4d5e006f7a8b04",
          "fullName": "Bob Williams",
          "userImages": {
            "chatImage": "https://cdn.weellu.com/pic100/avatar4.jpg",
            "smallImage": "https://cdn.weellu.com/si400/avatar4.jpg"
          },
          "bio": "Backend engineer"
        },
        "followingId": "665a1a2b3c4d5e006f7a8b01",
        "isEnable": true
      }
    ],
    "totalDocs": 58,
    "limit": 20,
    "page": 1,
    "totalPages": 3,
    "hasNextPage": true,
    "hasPrevPage": false,
    "nextPage": 2,
    "prevPage": null
  }
}

Get My Following

GET https://api.weellu.com/api/v1/follow/my-following

Returns a paginated list of users that the authenticated user follows.

Query Parameters

Parameter Type Required Description
page number No Page number, starting from 1. Defaults to 1.
limit number No Number of results per page. Defaults to 20.

Example Request

curl -X GET "https://api.weellu.com/api/v1/follow/my-following?page=1&limit=20" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/follow/my-following?page=1&limit=20",
  {
    headers: { "Authorization": "Bearer TOKEN" },
  }
);
const data = await response.json();
final response = await apiService.get(
  '/follow/my-following',
  parameters: {'page': '1', 'limit': '20'},
);

Example Response

{
  "data": {
    "docs": [
      {
        "_id": "665a3c4d5e6f7a008b9c0d03",
        "followerId": "665a1a2b3c4d5e006f7a8b01",
        "followingId": {
          "_id": "665a1a2b3c4d5e006f7a8b05",
          "fullName": "Carol Davis",
          "userImages": {
            "chatImage": "https://cdn.weellu.com/pic100/avatar5.jpg",
            "smallImage": "https://cdn.weellu.com/si400/avatar5.jpg"
          },
          "bio": "Product designer"
        },
        "isEnable": true
      }
    ],
    "totalDocs": 12,
    "limit": 20,
    "page": 1,
    "totalPages": 1,
    "hasNextPage": false,
    "hasPrevPage": false,
    "nextPage": null,
    "prevPage": null
  }
}

Remove Follower

DELETE https://api.weellu.com/api/v1/follow/remove-follower/:followerId

Removes a specific user from the authenticated user's followers list. This does not block the user -- they can follow again.

Path Parameters

Parameter Type Required Description
followerId string Yes MongoDB ObjectId of the follower to remove. Must be a valid 24-character hex string.

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/follow/remove-follower/665a1a2b3c4d5e006f7a8b03" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/follow/remove-follower/665a1a2b3c4d5e006f7a8b03",
  {
    method: "DELETE",
    headers: { "Authorization": "Bearer TOKEN" },
  }
);
const data = await response.json();
final response = await apiService.delete(
  '/follow/remove-follower/665a1a2b3c4d5e006f7a8b03',
);

Example Response

{
  "data": true
}

User Stories

Stories are ephemeral content that expires after 24 hours. They support text, image, video, and voice types with privacy controls.

Enums

StoryType

Value Description
text Text-only story with customizable background, font, and alignment
image Image story with optional caption
video Video story with optional caption
voice Voice/audio story
file File attachment story

StoryPrivacy

Value Description
public Visible to all users
followers Visible only to followers
following Visible only to users you follow
somePeople Visible only to specific users listed in somePeople

StoryScope

Value Description
all Broadcast to all eligible viewers
followers Scoped to followers
group Scoped to a group

StoryFontType

Value Description
normal Default font style
italic Italic font style
bold Bold font style

StoryTextAlign

Value Description
center Center-aligned text
left Left-aligned text
right Right-aligned text

Create Story

POST https://api.weellu.com/api/v1/user-story/

Creates a new story. Uses multipart form data to support file uploads (up to 4 files). Stories expire automatically after 24 hours.

Body Parameters (multipart/form-data)

Parameter Type Required Description
storyType string Yes Type of story: text, image, video, voice, or file
content string Yes Text content of the story. For non-text types, this is typically a description or transcript.
storyPrivacy string No Privacy level: public, followers, following, or somePeople. Defaults to public.
scope string No Distribution scope: all, followers, or group. Defaults to all.
attachment string (JSON) Conditional JSON string with media attachment metadata. Required for non-text story types. Must be valid JSON.
backgroundColor string No Hex color code for the story background (e.g., #FF5733). Used primarily for text stories.
textColor string No Hex color code for the text (e.g., #FFFFFF). Used primarily for text stories.
textAlign string No Text alignment: center, left, or right.
caption string No Optional caption overlaid on media stories.
fontType string Conditional Font style: normal, italic, or bold. Required when storyType is text.
somePeople string (JSON array) Conditional JSON array of MongoDB ObjectId strings. Required when storyPrivacy is somePeople. Each ID must be a valid 24-character hex string.
exceptPeople string (JSON array) No JSON array of MongoDB ObjectId strings for users to exclude from viewing. Each ID must be a valid 24-character hex string.
file File Conditional Media file(s). Up to 4 files. Required for non-text story types.

Example Request (Text Story)

curl -X POST "https://api.weellu.com/api/v1/user-story/" \
  -H "Authorization: Bearer TOKEN" \
  -F "storyType=text" \
  -F "content=Hello world! This is my first story." \
  -F "storyPrivacy=public" \
  -F "backgroundColor=#1A1A2E" \
  -F "textColor=#FFFFFF" \
  -F "textAlign=center" \
  -F "fontType=bold"
const formData = new FormData();
formData.append("storyType", "text");
formData.append("content", "Hello world! This is my first story.");
formData.append("storyPrivacy", "public");
formData.append("backgroundColor", "#1A1A2E");
formData.append("textColor", "#FFFFFF");
formData.append("textAlign", "center");
formData.append("fontType", "bold");

const response = await fetch("https://api.weellu.com/api/v1/user-story/", {
  method: "POST",
  headers: { "Authorization": "Bearer TOKEN" },
  body: formData,
});
const data = await response.json();
final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/user-story/'),
);
request.headers['Authorization'] = 'Bearer TOKEN';
request.fields['storyType'] = 'text';
request.fields['content'] = 'Hello world! This is my first story.';
request.fields['storyPrivacy'] = 'public';
request.fields['backgroundColor'] = '#1A1A2E';
request.fields['textColor'] = '#FFFFFF';
request.fields['textAlign'] = 'center';
request.fields['fontType'] = 'bold';

final response = await request.send();

Example Request (Image Story)

curl -X POST "https://api.weellu.com/api/v1/user-story/" \
  -H "Authorization: Bearer TOKEN" \
  -F "storyType=image" \
  -F "content=Check out this view!" \
  -F "storyPrivacy=followers" \
  -F "caption=Sunset at the beach" \
  -F "attachment={\"width\":1080,\"height\":1920}" \
  -F "file=@/path/to/photo.jpg"
const formData = new FormData();
formData.append("storyType", "image");
formData.append("content", "Check out this view!");
formData.append("storyPrivacy", "followers");
formData.append("caption", "Sunset at the beach");
formData.append("attachment", JSON.stringify({ width: 1080, height: 1920 }));
formData.append("file", imageFile);

const response = await fetch("https://api.weellu.com/api/v1/user-story/", {
  method: "POST",
  headers: { "Authorization": "Bearer TOKEN" },
  body: formData,
});
const data = await response.json();
final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/user-story/'),
);
request.headers['Authorization'] = 'Bearer TOKEN';
request.fields['storyType'] = 'image';
request.fields['content'] = 'Check out this view!';
request.fields['storyPrivacy'] = 'followers';
request.fields['caption'] = 'Sunset at the beach';
request.fields['attachment'] = '{"width":1080,"height":1920}';
request.files.add(await http.MultipartFile.fromPath('file', '/path/to/photo.jpg'));

final response = await request.send();

Example Response

{
  "data": {
    "_id": "665a4e5f6a7b8c009d0e1f23",
    "userId": "665a1a2b3c4d5e006f7a8b01",
    "storyType": "image",
    "storyPrivacy": "followers",
    "fontType": "normal",
    "content": "Check out this view!",
    "caption": "Sunset at the beach",
    "backgroundColor": null,
    "textColor": null,
    "textAlign": null,
    "somePeople": [],
    "att": {
      "width": 1080,
      "height": 1920,
      "url": "https://cdn.weellu.com/story/665a4e5f6a7b8c009d0e1f23.jpg",
      "thumbnail": "https://cdn.weellu.com/story/665a4e5f6a7b8c009d0e1f23_thumb.jpg"
    },
    "views": [],
    "likes": [],
    "posterId": null,
    "createdAt": "2026-03-18T12:00:00.000Z",
    "expireAt": "2026-03-19T12:00:00.000Z"
  }
}

Get All Stories Feed

GET https://api.weellu.com/api/v1/user-story/

Returns the stories feed for the authenticated user. This includes stories from followed users and public stories, respecting privacy settings. Results are paginated.

Query Parameters

Parameter Type Required Description
page number No Page number. Defaults to 1.
limit number No Number of results per page. Defaults to 20.

Example Request

curl -X GET "https://api.weellu.com/api/v1/user-story/?page=1&limit=20" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/user-story/?page=1&limit=20",
  {
    headers: { "Authorization": "Bearer TOKEN" },
  }
);
const data = await response.json();
final response = await apiService.get(
  '/user-story/',
  parameters: {'page': '1', 'limit': '20'},
);

Example Response

{
  "data": {
    "docs": [
      {
        "_id": "665a4e5f6a7b8c009d0e1f23",
        "userId": {
          "_id": "665a1a2b3c4d5e006f7a8b03",
          "fullName": "Alice Johnson",
          "userImages": {
            "chatImage": "https://cdn.weellu.com/pic100/avatar3.jpg"
          }
        },
        "storyType": "image",
        "storyPrivacy": "public",
        "fontType": "normal",
        "content": "Beautiful day!",
        "caption": "Morning vibes",
        "att": {
          "url": "https://cdn.weellu.com/story/665a4e5f6a7b8c009d0e1f23.jpg",
          "thumbnail": "https://cdn.weellu.com/story/665a4e5f6a7b8c009d0e1f23_thumb.jpg"
        },
        "views": ["665a1a2b3c4d5e006f7a8b01"],
        "likes": [],
        "createdAt": "2026-03-18T08:00:00.000Z",
        "expireAt": "2026-03-19T08:00:00.000Z"
      }
    ],
    "totalDocs": 15,
    "limit": 20,
    "page": 1,
    "totalPages": 1,
    "hasNextPage": false,
    "hasPrevPage": false,
    "nextPage": null,
    "prevPage": null
  }
}

Get My Stories

GET https://api.weellu.com/api/v1/user-story/me

Returns all active (non-expired) stories created by the authenticated user.

Parameters

No parameters required.

Example Request

curl -X GET "https://api.weellu.com/api/v1/user-story/me" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch("https://api.weellu.com/api/v1/user-story/me", {
  headers: { "Authorization": "Bearer TOKEN" },
});
const data = await response.json();
final response = await apiService.get('/user-story/me');

Example Response

{
  "data": [
    {
      "_id": "665a4e5f6a7b8c009d0e1f23",
      "userId": "665a1a2b3c4d5e006f7a8b01",
      "storyType": "text",
      "storyPrivacy": "public",
      "fontType": "bold",
      "content": "Excited about the new release!",
      "backgroundColor": "#6C63FF",
      "textColor": "#FFFFFF",
      "textAlign": "center",
      "caption": null,
      "att": null,
      "somePeople": [],
      "views": [
        "665a1a2b3c4d5e006f7a8b02",
        "665a1a2b3c4d5e006f7a8b03"
      ],
      "likes": [
        "665a1a2b3c4d5e006f7a8b02"
      ],
      "posterId": null,
      "createdAt": "2026-03-18T10:00:00.000Z",
      "expireAt": "2026-03-19T10:00:00.000Z"
    }
  ]
}

Get User's Stories

GET https://api.weellu.com/api/v1/user-story/:id/v2

Returns all active stories for a specific user, respecting privacy settings. If the target user has privacy-restricted stories, only stories visible to the authenticated user are returned.

Path Parameters

Parameter Type Required Description
id string Yes MongoDB ObjectId of the user whose stories to retrieve

Query Parameters

Parameter Type Required Description
page number No Page number. Defaults to 1.
limit number No Number of results per page. Defaults to 20.

Example Request

curl -X GET "https://api.weellu.com/api/v1/user-story/665a1a2b3c4d5e006f7a8b03/v2?page=1&limit=20" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/user-story/665a1a2b3c4d5e006f7a8b03/v2?page=1&limit=20",
  {
    headers: { "Authorization": "Bearer TOKEN" },
  }
);
const data = await response.json();
final response = await apiService.get(
  '/user-story/665a1a2b3c4d5e006f7a8b03/v2',
  parameters: {'page': '1', 'limit': '20'},
);

Example Response

{
  "data": {
    "docs": [
      {
        "_id": "665a4e5f6a7b8c009d0e1f24",
        "userId": "665a1a2b3c4d5e006f7a8b03",
        "storyType": "video",
        "storyPrivacy": "public",
        "fontType": "normal",
        "content": "New tutorial video",
        "caption": "Learn Flutter in 5 minutes",
        "att": {
          "url": "https://cdn.weellu.com/story/665a4e5f6a7b8c009d0e1f24.mp4",
          "thumbnail": "https://cdn.weellu.com/story/665a4e5f6a7b8c009d0e1f24_thumb.jpg",
          "duration": 300
        },
        "views": [],
        "likes": [],
        "createdAt": "2026-03-18T11:00:00.000Z",
        "expireAt": "2026-03-19T11:00:00.000Z"
      }
    ],
    "totalDocs": 3,
    "limit": 20,
    "page": 1,
    "totalPages": 1,
    "hasNextPage": false,
    "hasPrevPage": false,
    "nextPage": null,
    "prevPage": null
  }
}

Forward Story

POST https://api.weellu.com/api/v1/user-story/forward/:id

Forwards an existing story as a new story on the authenticated user's profile. The original story's media and content are copied, and the posterId field on the new story references the original creator.

Path Parameters

Parameter Type Required Description
id string Yes MongoDB ObjectId of the story to forward

Body Parameters

Parameter Type Required Description
caption string No Optional new caption for the forwarded story
scope string No Distribution scope: all, followers, or group
storyPrivacy string No Privacy level: public, followers, following, or somePeople
somePeople string (JSON array) Conditional JSON array of MongoDB ObjectId strings. Required when storyPrivacy is somePeople. Each ID must be a valid 24-character hex string.
exceptPeople string (JSON array) No JSON array of MongoDB ObjectId strings for users to exclude

Example Request

curl -X POST "https://api.weellu.com/api/v1/user-story/forward/665a4e5f6a7b8c009d0e1f23" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "caption": "Look at this amazing story!",
    "storyPrivacy": "public",
    "scope": "all"
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/user-story/forward/665a4e5f6a7b8c009d0e1f23",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      caption: "Look at this amazing story!",
      storyPrivacy: "public",
      scope: "all",
    }),
  }
);
const data = await response.json();
final response = await apiService.post(
  '/user-story/forward/665a4e5f6a7b8c009d0e1f23',
  body: {
    'caption': 'Look at this amazing story!',
    'storyPrivacy': 'public',
    'scope': 'all',
  },
);

Example Response

{
  "data": {
    "_id": "665a5f6a7b8c9d00e0f1a234",
    "userId": "665a1a2b3c4d5e006f7a8b01",
    "posterId": "665a1a2b3c4d5e006f7a8b03",
    "storyType": "image",
    "storyPrivacy": "public",
    "fontType": "normal",
    "content": "Check out this view!",
    "caption": "Look at this amazing story!",
    "att": {
      "url": "https://cdn.weellu.com/story/665a4e5f6a7b8c009d0e1f23.jpg",
      "thumbnail": "https://cdn.weellu.com/story/665a4e5f6a7b8c009d0e1f23_thumb.jpg"
    },
    "views": [],
    "likes": [],
    "somePeople": [],
    "createdAt": "2026-03-18T13:00:00.000Z",
    "expireAt": "2026-03-19T13:00:00.000Z"
  }
}

Reply to Story

POST https://api.weellu.com/api/v1/user-story/:id/reply

Sends a reply message to a story. The reply is delivered as a chat message to the story creator. Supports text and media replies via multipart form data (up to 2 files).

Path Parameters

Parameter Type Required Description
id string Yes MongoDB ObjectId of the story to reply to

Body Parameters (multipart/form-data)

Parameter Type Required Description
content string Yes Reply message text content
localId string Yes Client-generated UUID v4 for deduplication
messageType string Yes Type of reply message: text, image, video, voice, or file
attachment string (JSON) Conditional JSON string with attachment metadata. Required for non-text message types. Must be valid JSON.
linkAtt string (JSON) No JSON string with link preview metadata. Must be valid JSON.
storyId string No MongoDB ObjectId of the story being replied to (auto-filled from path parameter)
file File Conditional Media file(s). Up to 2 files. Required when messageType is image, video, voice, or file.

Example Request (Text Reply)

curl -X POST "https://api.weellu.com/api/v1/user-story/665a4e5f6a7b8c009d0e1f23/reply" \
  -H "Authorization: Bearer TOKEN" \
  -F "content=This is amazing! Where was this taken?" \
  -F "localId=a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -F "messageType=text"
const formData = new FormData();
formData.append("content", "This is amazing! Where was this taken?");
formData.append("localId", "a1b2c3d4-e5f6-7890-abcd-ef1234567890");
formData.append("messageType", "text");

const response = await fetch(
  "https://api.weellu.com/api/v1/user-story/665a4e5f6a7b8c009d0e1f23/reply",
  {
    method: "POST",
    headers: { "Authorization": "Bearer TOKEN" },
    body: formData,
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/user-story/665a4e5f6a7b8c009d0e1f23/reply'),
);
request.headers['Authorization'] = 'Bearer TOKEN';
request.fields['content'] = 'This is amazing! Where was this taken?';
request.fields['localId'] = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890';
request.fields['messageType'] = 'text';

final response = await request.send();

Example Request (Image Reply)

curl -X POST "https://api.weellu.com/api/v1/user-story/665a4e5f6a7b8c009d0e1f23/reply" \
  -H "Authorization: Bearer TOKEN" \
  -F "content=Here is my view!" \
  -F "localId=b2c3d4e5-f6a7-8901-bcde-f12345678901" \
  -F "messageType=image" \
  -F "attachment={\"width\":1080,\"height\":720}" \
  -F "file=@/path/to/reply-photo.jpg"
const formData = new FormData();
formData.append("content", "Here is my view!");
formData.append("localId", "b2c3d4e5-f6a7-8901-bcde-f12345678901");
formData.append("messageType", "image");
formData.append("attachment", JSON.stringify({ width: 1080, height: 720 }));
formData.append("file", replyImageFile);

const response = await fetch(
  "https://api.weellu.com/api/v1/user-story/665a4e5f6a7b8c009d0e1f23/reply",
  {
    method: "POST",
    headers: { "Authorization": "Bearer TOKEN" },
    body: formData,
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/user-story/665a4e5f6a7b8c009d0e1f23/reply'),
);
request.headers['Authorization'] = 'Bearer TOKEN';
request.fields['content'] = 'Here is my view!';
request.fields['localId'] = 'b2c3d4e5-f6a7-8901-bcde-f12345678901';
request.fields['messageType'] = 'image';
request.fields['attachment'] = '{"width":1080,"height":720}';
request.files.add(await http.MultipartFile.fromPath('file', '/path/to/reply-photo.jpg'));

final response = await request.send();

Example Response

{
  "data": {
    "_id": "665a6a7b8c9d0e00f1a2b345",
    "sId": "665a1a2b3c4d5e006f7a8b01",
    "sName": "John Doe",
    "sImg": "https://cdn.weellu.com/pic100/avatar1.jpg",
    "rId": "665a1f3b2e4c8a001d3b7f03",
    "c": "This is amazing! Where was this taken?",
    "mT": "text",
    "lId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "msgAtt": null,
    "createdAt": "2026-03-18T14:00:00.000Z"
  }
}

Repost Story

POST https://api.weellu.com/api/v1/user-story/:id/repost

Reposts an existing story to the authenticated user's story feed. Unlike forwarding, a repost may link directly to the original story.

Path Parameters

Parameter Type Required Description
id string Yes MongoDB ObjectId of the story to repost

Body Parameters

Parameter Type Required Description
scope string No Distribution scope: all, followers, or group
storyPrivacy string No Privacy level: public, followers, following, or somePeople
somePeople string (JSON array) Conditional JSON array of MongoDB ObjectId strings. Required when storyPrivacy is somePeople. Each ID must be a valid 24-character hex string.
exceptPeople string (JSON array) No JSON array of MongoDB ObjectId strings for users to exclude

Example Request

curl -X POST "https://api.weellu.com/api/v1/user-story/665a4e5f6a7b8c009d0e1f23/repost" \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "storyPrivacy": "followers",
    "scope": "all"
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/user-story/665a4e5f6a7b8c009d0e1f23/repost",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      storyPrivacy: "followers",
      scope: "all",
    }),
  }
);
const data = await response.json();
final response = await apiService.post(
  '/user-story/665a4e5f6a7b8c009d0e1f23/repost',
  body: {
    'storyPrivacy': 'followers',
    'scope': 'all',
  },
);

Example Response

{
  "data": {
    "_id": "665a7b8c9d0e1f00a2b3c456",
    "userId": "665a1a2b3c4d5e006f7a8b01",
    "posterId": "665a1a2b3c4d5e006f7a8b03",
    "storyType": "image",
    "storyPrivacy": "followers",
    "fontType": "normal",
    "content": "Check out this view!",
    "att": {
      "url": "https://cdn.weellu.com/story/665a4e5f6a7b8c009d0e1f23.jpg",
      "thumbnail": "https://cdn.weellu.com/story/665a4e5f6a7b8c009d0e1f23_thumb.jpg"
    },
    "views": [],
    "likes": [],
    "somePeople": [],
    "createdAt": "2026-03-18T15:00:00.000Z",
    "expireAt": "2026-03-19T15:00:00.000Z"
  }
}

Delete Story

DELETE https://api.weellu.com/api/v1/user-story/:id

Permanently deletes a story. Only the story creator can delete their own stories.

Path Parameters

Parameter Type Required Description
id string Yes MongoDB ObjectId of the story to delete

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/user-story/665a4e5f6a7b8c009d0e1f23" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/user-story/665a4e5f6a7b8c009d0e1f23",
  {
    method: "DELETE",
    headers: { "Authorization": "Bearer TOKEN" },
  }
);
const data = await response.json();
final response = await apiService.delete(
  '/user-story/665a4e5f6a7b8c009d0e1f23',
);

Example Response

{
  "data": true
}

Add View

POST https://api.weellu.com/api/v1/user-story/views/:id

Records that the authenticated user has viewed the specified story. Duplicate views from the same user are ignored.

Path Parameters

Parameter Type Required Description
id string Yes MongoDB ObjectId of the story being viewed

Example Request

curl -X POST "https://api.weellu.com/api/v1/user-story/views/665a4e5f6a7b8c009d0e1f23" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/user-story/views/665a4e5f6a7b8c009d0e1f23",
  {
    method: "POST",
    headers: { "Authorization": "Bearer TOKEN" },
  }
);
const data = await response.json();
final response = await apiService.post(
  '/user-story/views/665a4e5f6a7b8c009d0e1f23',
);

Example Response

{
  "data": true
}

Toggle Like

POST https://api.weellu.com/api/v1/user-story/likes/:id

Toggles the like state on a story for the authenticated user. If not liked, this adds a like. If already liked, this removes it. The story creator receives a push notification on new likes.

Path Parameters

Parameter Type Required Description
id string Yes MongoDB ObjectId of the story to like or unlike

Example Request

curl -X POST "https://api.weellu.com/api/v1/user-story/likes/665a4e5f6a7b8c009d0e1f23" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/user-story/likes/665a4e5f6a7b8c009d0e1f23",
  {
    method: "POST",
    headers: { "Authorization": "Bearer TOKEN" },
  }
);
const data = await response.json();
final response = await apiService.post(
  '/user-story/likes/665a4e5f6a7b8c009d0e1f23',
);

Example Response (liked)

{
  "data": true
}

Example Response (unliked)

{
  "data": false
}

Get Story Viewers

GET https://api.weellu.com/api/v1/user-story/views/:id

Returns a paginated list of users who have viewed the specified story. Only the story creator can access this endpoint.

Path Parameters

Parameter Type Required Description
id string Yes MongoDB ObjectId of the story

Query Parameters

Parameter Type Required Description
page number No Page number. Defaults to 1.
limit number No Number of results per page. Defaults to 30.

Example Request

curl -X GET "https://api.weellu.com/api/v1/user-story/views/665a4e5f6a7b8c009d0e1f23?page=1&limit=30" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/user-story/views/665a4e5f6a7b8c009d0e1f23?page=1&limit=30",
  {
    headers: { "Authorization": "Bearer TOKEN" },
  }
);
const data = await response.json();
final response = await apiService.get(
  '/user-story/views/665a4e5f6a7b8c009d0e1f23',
  parameters: {'page': '1', 'limit': '30'},
);

Example Response

{
  "data": {
    "docs": [
      {
        "_id": "665a1a2b3c4d5e006f7a8b02",
        "fullName": "Jane Smith",
        "userImages": {
          "chatImage": "https://cdn.weellu.com/pic100/avatar2.jpg",
          "smallImage": "https://cdn.weellu.com/si400/avatar2.jpg"
        }
      },
      {
        "_id": "665a1a2b3c4d5e006f7a8b03",
        "fullName": "Alice Johnson",
        "userImages": {
          "chatImage": "https://cdn.weellu.com/pic100/avatar3.jpg",
          "smallImage": "https://cdn.weellu.com/si400/avatar3.jpg"
        }
      }
    ],
    "totalDocs": 25,
    "limit": 30,
    "page": 1,
    "totalPages": 1,
    "hasNextPage": false,
    "hasPrevPage": false,
    "nextPage": null,
    "prevPage": null
  }
}

Get Story Likers

GET https://api.weellu.com/api/v1/user-story/likes/:id

Returns a paginated list of users who have liked the specified story.

Path Parameters

Parameter Type Required Description
id string Yes MongoDB ObjectId of the story

Query Parameters

Parameter Type Required Description
page number No Page number. Defaults to 1.
limit number No Number of results per page. Defaults to 30.

Example Request

curl -X GET "https://api.weellu.com/api/v1/user-story/likes/665a4e5f6a7b8c009d0e1f23?page=1&limit=30" \
  -H "Authorization: Bearer TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/user-story/likes/665a4e5f6a7b8c009d0e1f23?page=1&limit=30",
  {
    headers: { "Authorization": "Bearer TOKEN" },
  }
);
const data = await response.json();
final response = await apiService.get(
  '/user-story/likes/665a4e5f6a7b8c009d0e1f23',
  parameters: {'page': '1', 'limit': '30'},
);

Example Response

{
  "data": {
    "docs": [
      {
        "_id": "665a1a2b3c4d5e006f7a8b04",
        "fullName": "Bob Williams",
        "userImages": {
          "chatImage": "https://cdn.weellu.com/pic100/avatar4.jpg",
          "smallImage": "https://cdn.weellu.com/si400/avatar4.jpg"
        }
      }
    ],
    "totalDocs": 1,
    "limit": 30,
    "page": 1,
    "totalPages": 1,
    "hasNextPage": false,
    "hasPrevPage": false,
    "nextPage": null,
    "prevPage": null
  }
}

Activity Notifications

Activity notifications keep users informed about events relevant to them, such as story interactions, group additions, mentions, and follows.

All notification endpoints require Bearer token authentication.

Get Notification Feed

GET https://api.weellu.com/api/v1/activity-notifications/feed

Returns a paginated feed of the authenticated user's activity notifications, ordered by most recent first.

Query Parameters

Parameter Type Required Description
page number No Page number for pagination. Default: 1
limit number No Number of notifications per page. Default: 20

Example Request

curl "https://api.weellu.com/api/v1/activity-notifications/feed?page=1&limit=20" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/activity-notifications/feed?page=1&limit=20",
  {
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/activity-notifications/feed',
  parameters: {'page': 1, 'limit': 20},
);

Example Response

{
  "code": 200,
  "data": {
    "data": [
      {
        "_id": "660a1b2c3d4e5f6a7b8c9d0e",
        "userId": "659f1a2b3c4d5e6f7a8b9c0d",
        "type": "story_like",
        "actorUserId": "659f2b3c4d5e6f7a8b9c0d1e",
        "actorUserName": "John Doe",
        "targetId": "660b2c3d4e5f6a7b8c9d0e1f",
        "targetName": "My Story",
        "targetType": "story",
        "message": null,
        "isRead": false,
        "createdAt": "2026-03-18T10:30:00.000Z"
      },
      {
        "_id": "660a1b2c3d4e5f6a7b8c9d0f",
        "userId": "659f1a2b3c4d5e6f7a8b9c0d",
        "type": "group_mention",
        "actorUserId": "659f3c4d5e6f7a8b9c0d1e2f",
        "actorUserName": "Jane Smith",
        "targetId": "660c3d4e5f6a7b8c9d0e1f2a",
        "targetName": "Project Alpha",
        "targetType": "group",
        "message": "mentioned you in a message",
        "isRead": true,
        "createdAt": "2026-03-18T09:15:00.000Z"
      }
    ],
    "pagination": {
      "totalDocs": 42,
      "limit": 20,
      "page": 1,
      "totalPages": 3,
      "hasNextPage": true,
      "hasPrevPage": false
    }
  }
}

Response Fields

Field Type Description
data array Array of notification objects
data[]._id string Unique notification ID
data[].userId string ID of the user who owns the notification
data[].type string Notification type. One of: story_like, story_reply, group_addition, project_addition, group_mention, project_mention, single_mention, follow
data[].actorUserId string ID of the user who triggered the notification
data[].actorUserName string Display name of the actor user
data[].targetId string ID of the target entity (story, group, project, or message). Nullable
data[].targetName string Name of the target entity. Nullable
data[].targetType string Type of the target. One of: story, group, project, message. Nullable
data[].message string Optional human-readable message. Nullable
data[].isRead boolean Whether the notification has been read
data[].createdAt string ISO 8601 timestamp when the notification was created
pagination object Pagination metadata
pagination.totalDocs number Total number of notifications
pagination.limit number Items per page
pagination.page number Current page number
pagination.totalPages number Total number of pages
pagination.hasNextPage boolean Whether there is a next page
pagination.hasPrevPage boolean Whether there is a previous page

Get Aggregated Feed

GET https://api.weellu.com/api/v1/activity-notifications/feed/aggregated

Returns an aggregated view of notifications, grouping similar notifications together (e.g., "John and 3 others liked your story").

Query Parameters

Parameter Type Required Description
page number No Page number for pagination. Default: 1
limit number No Number of aggregated items per page. Default: 20

Example Request

curl "https://api.weellu.com/api/v1/activity-notifications/feed/aggregated?page=1&limit=20" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/activity-notifications/feed/aggregated?page=1&limit=20",
  {
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/activity-notifications/feed/aggregated',
  parameters: {'page': 1, 'limit': 20},
);

Example Response

{
  "code": 200,
  "data": {
    "data": [
      {
        "type": "story_like",
        "targetId": "660b2c3d4e5f6a7b8c9d0e1f",
        "targetName": "My Story",
        "targetType": "story",
        "count": 4,
        "actors": [
          {
            "actorUserId": "659f2b3c4d5e6f7a8b9c0d1e",
            "actorUserName": "John Doe"
          },
          {
            "actorUserId": "659f3c4d5e6f7a8b9c0d1e2f",
            "actorUserName": "Jane Smith"
          }
        ],
        "latestAt": "2026-03-18T10:30:00.000Z",
        "isRead": false
      }
    ],
    "pagination": {
      "totalDocs": 15,
      "limit": 20,
      "page": 1,
      "totalPages": 1,
      "hasNextPage": false,
      "hasPrevPage": false
    }
  }
}

Response Fields

Field Type Description
data array Array of aggregated notification groups
data[].type string Notification type shared by the group
data[].targetId string ID of the shared target entity
data[].targetName string Name of the shared target entity
data[].targetType string Type of the shared target
data[].count number Total number of notifications in this group
data[].actors array List of actor users in this group
data[].actors[].actorUserId string ID of an actor user
data[].actors[].actorUserName string Display name of an actor user
data[].latestAt string ISO 8601 timestamp of the most recent notification in the group
data[].isRead boolean Whether all notifications in the group have been read
pagination object Pagination metadata (same structure as feed endpoint)

Get Unread Notifications

GET https://api.weellu.com/api/v1/activity-notifications/unread

Returns all unread notifications for the authenticated user.

Parameters

No parameters required.

Example Request

curl "https://api.weellu.com/api/v1/activity-notifications/unread" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/activity-notifications/unread",
  {
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/activity-notifications/unread',
);

Example Response

{
  "code": 200,
  "data": {
    "data": [
      {
        "_id": "660a1b2c3d4e5f6a7b8c9d0e",
        "userId": "659f1a2b3c4d5e6f7a8b9c0d",
        "type": "follow",
        "actorUserId": "659f2b3c4d5e6f7a8b9c0d1e",
        "actorUserName": "John Doe",
        "targetId": null,
        "targetName": null,
        "targetType": null,
        "message": null,
        "isRead": false,
        "createdAt": "2026-03-18T10:30:00.000Z"
      }
    ],
    "count": 1
  }
}

Response Fields

Field Type Description
data array Array of unread notification objects (same structure as feed)
count number Total number of unread notifications returned

Get Unread Count

GET https://api.weellu.com/api/v1/activity-notifications/unread/count

Returns the count of unread notifications for the authenticated user. Useful for displaying badge counts.

Parameters

No parameters required.

Example Request

curl "https://api.weellu.com/api/v1/activity-notifications/unread/count" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/activity-notifications/unread/count",
  {
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/activity-notifications/unread/count',
);

Example Response

{
  "code": 200,
  "data": {
    "unreadCount": 7
  }
}

Response Fields

Field Type Description
unreadCount number Total number of unread notifications

Get Notifications by Type

GET https://api.weellu.com/api/v1/activity-notifications/by-type/:type

Returns a paginated list of notifications filtered by a specific notification type.

Path Parameters

Parameter Type Required Description
type string Yes The notification type to filter by. One of: story_like, story_reply, group_addition, project_addition, group_mention, project_mention, single_mention, follow

Query Parameters

Parameter Type Required Description
page number No Page number for pagination. Default: 1
limit number No Number of notifications per page. Default: 20

Example Request

curl "https://api.weellu.com/api/v1/activity-notifications/by-type/story_like?page=1&limit=10" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/activity-notifications/by-type/story_like?page=1&limit=10",
  {
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/activity-notifications/by-type/story_like',
  parameters: {'page': 1, 'limit': 10},
);

Example Response

{
  "code": 200,
  "data": {
    "data": [
      {
        "_id": "660a1b2c3d4e5f6a7b8c9d0e",
        "userId": "659f1a2b3c4d5e6f7a8b9c0d",
        "type": "story_like",
        "actorUserId": "659f2b3c4d5e6f7a8b9c0d1e",
        "actorUserName": "John Doe",
        "targetId": "660b2c3d4e5f6a7b8c9d0e1f",
        "targetName": "My Story",
        "targetType": "story",
        "message": null,
        "isRead": false,
        "createdAt": "2026-03-18T10:30:00.000Z"
      }
    ],
    "pagination": {
      "totalDocs": 5,
      "limit": 10,
      "page": 1,
      "totalPages": 1,
      "hasNextPage": false,
      "hasPrevPage": false
    }
  }
}

Response Fields

Same response structure as the Get Notification Feed endpoint, but filtered to the specified type.

Mark Notifications as Read

PUT https://api.weellu.com/api/v1/activity-notifications/mark-as-read

Marks one or more notifications as read. You can either pass specific notification IDs or mark all as read.

Body Parameters

Parameter Type Required Description
notificationIds string[] No Array of notification IDs (MongoDB ObjectIds) to mark as read
markAllAsRead boolean No If true, marks all unread notifications as read regardless of notificationIds

Example Request

curl -X PUT "https://api.weellu.com/api/v1/activity-notifications/mark-as-read" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "notificationIds": [
      "660a1b2c3d4e5f6a7b8c9d0e",
      "660a1b2c3d4e5f6a7b8c9d0f"
    ]
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/activity-notifications/mark-as-read",
  {
    method: "PUT",
    headers: {
      Authorization: "Bearer YOUR_JWT_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      notificationIds: [
        "660a1b2c3d4e5f6a7b8c9d0e",
        "660a1b2c3d4e5f6a7b8c9d0f",
      ],
    }),
  }
);
const data = await response.json();
final response = await chopper.put(
  '/api/v1/activity-notifications/mark-as-read',
  body: {
    'notificationIds': [
      '660a1b2c3d4e5f6a7b8c9d0e',
      '660a1b2c3d4e5f6a7b8c9d0f',
    ],
  },
);

Example Response

{
  "code": 200,
  "data": {
    "message": "Notifications marked as read"
  }
}

Mark Single Notification as Read

PUT https://api.weellu.com/api/v1/activity-notifications/:id/read

Marks a single notification as read and returns the updated notification.

Path Parameters

Parameter Type Required Description
id string Yes The notification ID (MongoDB ObjectId)

Example Request

curl -X PUT "https://api.weellu.com/api/v1/activity-notifications/660a1b2c3d4e5f6a7b8c9d0e/read" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/activity-notifications/660a1b2c3d4e5f6a7b8c9d0e/read",
  {
    method: "PUT",
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.put(
  '/api/v1/activity-notifications/660a1b2c3d4e5f6a7b8c9d0e/read',
);

Example Response

{
  "code": 200,
  "data": {
    "data": {
      "_id": "660a1b2c3d4e5f6a7b8c9d0e",
      "userId": "659f1a2b3c4d5e6f7a8b9c0d",
      "type": "story_like",
      "actorUserId": "659f2b3c4d5e6f7a8b9c0d1e",
      "actorUserName": "John Doe",
      "targetId": "660b2c3d4e5f6a7b8c9d0e1f",
      "targetName": "My Story",
      "targetType": "story",
      "message": null,
      "isRead": true,
      "createdAt": "2026-03-18T10:30:00.000Z"
    }
  }
}

Response Fields

Field Type Description
data object The updated notification object with isRead set to true

Delete Notifications

DELETE https://api.weellu.com/api/v1/activity-notifications

Deletes specific notifications by their IDs.

Body Parameters

Parameter Type Required Description
notificationIds string[] Yes Array of notification IDs (MongoDB ObjectIds) to delete

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/activity-notifications" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "notificationIds": [
      "660a1b2c3d4e5f6a7b8c9d0e",
      "660a1b2c3d4e5f6a7b8c9d0f"
    ]
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/activity-notifications",
  {
    method: "DELETE",
    headers: {
      Authorization: "Bearer YOUR_JWT_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      notificationIds: [
        "660a1b2c3d4e5f6a7b8c9d0e",
        "660a1b2c3d4e5f6a7b8c9d0f",
      ],
    }),
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/api/v1/activity-notifications',
  body: {
    'notificationIds': [
      '660a1b2c3d4e5f6a7b8c9d0e',
      '660a1b2c3d4e5f6a7b8c9d0f',
    ],
  },
);

Example Response

{
  "code": 200,
  "data": {
    "message": "Notifications deleted successfully"
  }
}

Delete All Notifications

DELETE https://api.weellu.com/api/v1/activity-notifications/all

Deletes all notifications for the authenticated user. This action is irreversible.

Parameters

No parameters required.

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/activity-notifications/all" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/activity-notifications/all",
  {
    method: "DELETE",
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/api/v1/activity-notifications/all',
);

Example Response

{
  "code": 200,
  "data": {
    "message": "All notifications have been deleted"
  }
}

Delete Notifications by Type and Target

DELETE https://api.weellu.com/api/v1/activity-notifications/by-type-target

Deletes all notifications matching a specific type and target combination. Useful for cleaning up notifications related to a deleted entity.

Query Parameters

Parameter Type Required Description
type string Yes The notification type. One of: story_like, story_reply, group_addition, project_addition, group_mention, project_mention, single_mention, follow
targetId string Yes The target entity ID (MongoDB ObjectId)

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/activity-notifications/by-type-target?type=story_like&targetId=660b2c3d4e5f6a7b8c9d0e1f" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/activity-notifications/by-type-target?type=story_like&targetId=660b2c3d4e5f6a7b8c9d0e1f",
  {
    method: "DELETE",
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/api/v1/activity-notifications/by-type-target',
  parameters: {
    'type': 'story_like',
    'targetId': '660b2c3d4e5f6a7b8c9d0e1f',
  },
);

Example Response

{
  "code": 200,
  "data": {
    "message": "Deleted notifications: 3",
    "deletedCount": 3
  }
}

Response Fields

Field Type Description
message string Human-readable confirmation with count
deletedCount number Number of notifications that were deleted

Supporting Services

This section covers auxiliary services that support the core Weellu platform: user banning, room filters, reports, file uploads, bots, and the marketplace.

All endpoints require Bearer token authentication unless otherwise noted.

User Ban

Manage user-to-user blocking. When a user bans another user, all direct communication between them is blocked.

Check Ban Status

GET https://api.weellu.com/api/v1/user-ban/:peerId/ban

Checks the ban relationship between the authenticated user and a peer user. Returns whether either party has banned the other and the associated room ID if one exists.

Path Parameters

Parameter Type Required Description
peerId string Yes The peer user's ID (MongoDB ObjectId)

Example Request

curl "https://api.weellu.com/api/v1/user-ban/659f2b3c4d5e6f7a8b9c0d1e/ban" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/user-ban/659f2b3c4d5e6f7a8b9c0d1e/ban",
  {
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/user-ban/659f2b3c4d5e6f7a8b9c0d1e/ban',
);

Example Response

{
  "code": 200,
  "data": {
    "isMeBanner": false,
    "isPeerBanner": false,
    "roomId": "660d4e5f6a7b8c9d0e1f2a3b"
  }
}

Response Fields

Field Type Description
isMeBanner boolean true if the authenticated user has banned the peer
isPeerBanner boolean true if the peer user has banned the authenticated user
roomId string The direct chat room ID between the two users. Nullable if no room exists

Ban User

POST https://api.weellu.com/api/v1/user-ban/:peerId/ban

Bans a peer user. The banned user will no longer be able to send messages to the authenticated user.

Path Parameters

Parameter Type Required Description
peerId string Yes The peer user's ID (MongoDB ObjectId)

Example Request

curl -X POST "https://api.weellu.com/api/v1/user-ban/659f2b3c4d5e6f7a8b9c0d1e/ban" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/user-ban/659f2b3c4d5e6f7a8b9c0d1e/ban",
  {
    method: "POST",
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.post(
  '/api/v1/user-ban/659f2b3c4d5e6f7a8b9c0d1e/ban',
);

Example Response

{
  "code": 200,
  "data": {
    "isMeBanner": true,
    "isPeerBanner": false,
    "roomId": "660d4e5f6a7b8c9d0e1f2a3b"
  }
}

Unban User

POST https://api.weellu.com/api/v1/user-ban/:peerId/un-ban

Removes a ban on a peer user. The peer user will be able to communicate with the authenticated user again.

Path Parameters

Parameter Type Required Description
peerId string Yes The peer user's ID (MongoDB ObjectId)

Example Request

curl -X POST "https://api.weellu.com/api/v1/user-ban/659f2b3c4d5e6f7a8b9c0d1e/un-ban" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/user-ban/659f2b3c4d5e6f7a8b9c0d1e/un-ban",
  {
    method: "POST",
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.post(
  '/api/v1/user-ban/659f2b3c4d5e6f7a8b9c0d1e/un-ban',
);

Example Response

{
  "code": 200,
  "data": {
    "isMeBanner": false,
    "isPeerBanner": false,
    "roomId": "660d4e5f6a7b8c9d0e1f2a3b"
  }
}

Room Filters

Room filters allow users to organize their chat rooms into custom named groups. Each filter has a name and a list of room IDs.

Create Room Filter

POST https://api.weellu.com/api/v1/room-filters

Creates a new room filter for the authenticated user.

Body Parameters

Parameter Type Required Description
name string Yes Display name for the filter
rIds string[] No Array of room IDs (MongoDB ObjectIds) to include in the filter

Example Request

curl -X POST "https://api.weellu.com/api/v1/room-filters" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Work Chats",
    "rIds": [
      "660d4e5f6a7b8c9d0e1f2a3b",
      "660d4e5f6a7b8c9d0e1f2a3c"
    ]
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/room-filters",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_JWT_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      name: "Work Chats",
      rIds: [
        "660d4e5f6a7b8c9d0e1f2a3b",
        "660d4e5f6a7b8c9d0e1f2a3c",
      ],
    }),
  }
);
const data = await response.json();
final response = await chopper.post(
  '/api/v1/room-filters',
  body: {
    'name': 'Work Chats',
    'rIds': [
      '660d4e5f6a7b8c9d0e1f2a3b',
      '660d4e5f6a7b8c9d0e1f2a3c',
    ],
  },
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "660e5f6a7b8c9d0e1f2a3b4c",
    "userId": "659f1a2b3c4d5e6f7a8b9c0d",
    "name": "Work Chats",
    "rIds": [
      "660d4e5f6a7b8c9d0e1f2a3b",
      "660d4e5f6a7b8c9d0e1f2a3c"
    ],
    "createdAt": "2026-03-18T10:30:00.000Z",
    "updatedAt": "2026-03-18T10:30:00.000Z"
  }
}

Response Fields

Field Type Description
_id string Unique filter ID
userId string Owner user ID
name string Filter display name
rIds string[] Array of room IDs in this filter
createdAt string ISO 8601 creation timestamp
updatedAt string ISO 8601 last update timestamp

Get All Room Filters

GET https://api.weellu.com/api/v1/room-filters

Returns all room filters belonging to the authenticated user.

Parameters

No parameters required.

Example Request

curl "https://api.weellu.com/api/v1/room-filters" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/room-filters",
  {
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/room-filters',
);

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "660e5f6a7b8c9d0e1f2a3b4c",
      "userId": "659f1a2b3c4d5e6f7a8b9c0d",
      "name": "Work Chats",
      "rIds": [
        "660d4e5f6a7b8c9d0e1f2a3b",
        "660d4e5f6a7b8c9d0e1f2a3c"
      ],
      "createdAt": "2026-03-18T10:30:00.000Z",
      "updatedAt": "2026-03-18T10:30:00.000Z"
    },
    {
      "_id": "660e5f6a7b8c9d0e1f2a3b4d",
      "userId": "659f1a2b3c4d5e6f7a8b9c0d",
      "name": "Family",
      "rIds": [
        "660d4e5f6a7b8c9d0e1f2a3d"
      ],
      "createdAt": "2026-03-17T08:00:00.000Z",
      "updatedAt": "2026-03-17T08:00:00.000Z"
    }
  ]
}

Update Room Filter

PATCH https://api.weellu.com/api/v1/room-filters/:id

Updates an existing room filter. You can change the name, the room list, or both.

Path Parameters

Parameter Type Required Description
id string Yes The filter ID (MongoDB ObjectId)

Body Parameters

Parameter Type Required Description
name string No New display name for the filter
rIds string[] No New array of room IDs. Replaces the entire list

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/room-filters/660e5f6a7b8c9d0e1f2a3b4c" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Work & Projects",
    "rIds": [
      "660d4e5f6a7b8c9d0e1f2a3b",
      "660d4e5f6a7b8c9d0e1f2a3c",
      "660d4e5f6a7b8c9d0e1f2a3e"
    ]
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/room-filters/660e5f6a7b8c9d0e1f2a3b4c",
  {
    method: "PATCH",
    headers: {
      Authorization: "Bearer YOUR_JWT_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      name: "Work & Projects",
      rIds: [
        "660d4e5f6a7b8c9d0e1f2a3b",
        "660d4e5f6a7b8c9d0e1f2a3c",
        "660d4e5f6a7b8c9d0e1f2a3e",
      ],
    }),
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/api/v1/room-filters/660e5f6a7b8c9d0e1f2a3b4c',
  body: {
    'name': 'Work & Projects',
    'rIds': [
      '660d4e5f6a7b8c9d0e1f2a3b',
      '660d4e5f6a7b8c9d0e1f2a3c',
      '660d4e5f6a7b8c9d0e1f2a3e',
    ],
  },
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "660e5f6a7b8c9d0e1f2a3b4c",
    "userId": "659f1a2b3c4d5e6f7a8b9c0d",
    "name": "Work & Projects",
    "rIds": [
      "660d4e5f6a7b8c9d0e1f2a3b",
      "660d4e5f6a7b8c9d0e1f2a3c",
      "660d4e5f6a7b8c9d0e1f2a3e"
    ],
    "createdAt": "2026-03-18T10:30:00.000Z",
    "updatedAt": "2026-03-18T11:00:00.000Z"
  }
}

Delete Room Filter

DELETE https://api.weellu.com/api/v1/room-filters/:id

Deletes a room filter. This does not affect the rooms themselves, only removes the filter grouping.

Path Parameters

Parameter Type Required Description
id string Yes The filter ID (MongoDB ObjectId)

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/room-filters/660e5f6a7b8c9d0e1f2a3b4c" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/room-filters/660e5f6a7b8c9d0e1f2a3b4c",
  {
    method: "DELETE",
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/api/v1/room-filters/660e5f6a7b8c9d0e1f2a3b4c',
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "660e5f6a7b8c9d0e1f2a3b4c",
    "userId": "659f1a2b3c4d5e6f7a8b9c0d",
    "name": "Work Chats",
    "rIds": [],
    "createdAt": "2026-03-18T10:30:00.000Z",
    "updatedAt": "2026-03-18T11:15:00.000Z"
  }
}

Report System

Submit bug reports, crash logs, and user feedback. Reports are stored with platform information for debugging.

Create Report

POST https://api.weellu.com/api/v1/report-system

Submits a new report to the system. Reports are automatically tagged with the user's platform information.

Body Parameters

Parameter Type Required Description
content string Yes Human-readable description of the issue
stack string Yes Stack trace or technical error details
type string Yes Report category (e.g., crash, bug, feedback, abuse)

Example Request

curl -X POST "https://api.weellu.com/api/v1/report-system" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "App crashes when opening group chat with 100+ members",
    "stack": "Error: RangeError (index): Invalid value\n  at GroupChatWidget.build (group_chat.dart:142)\n  at StatelessElement.build (framework.dart:4748)",
    "type": "crash"
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/report-system",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_JWT_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      content: "App crashes when opening group chat with 100+ members",
      stack: "Error: RangeError (index): Invalid value\n  at GroupChatWidget.build (group_chat.dart:142)",
      type: "crash",
    }),
  }
);
const data = await response.json();
final response = await chopper.post(
  '/api/v1/report-system',
  body: {
    'content': 'App crashes when opening group chat with 100+ members',
    'stack': 'Error: RangeError (index): Invalid value...',
    'type': 'crash',
  },
);

Example Response

{
  "_id": "660f6a7b8c9d0e1f2a3b4c5d",
  "content": "App crashes when opening group chat with 100+ members",
  "stack": "Error: RangeError (index): Invalid value\n  at GroupChatWidget.build (group_chat.dart:142)\n  at StatelessElement.build (framework.dart:4748)",
  "type": "crash",
  "platform": "android",
  "uId": "659f1a2b3c4d5e6f7a8b9c0d",
  "createdAt": "2026-03-18T10:30:00.000Z",
  "updatedAt": "2026-03-18T10:30:00.000Z"
}

Response Fields

Field Type Description
_id string Unique report ID
content string Report description
stack string Stack trace or technical details
type string Report category
platform string Platform from which the report was submitted (e.g., android, ios, web)
uId string ID of the user who submitted the report
createdAt string ISO 8601 creation timestamp
updatedAt string ISO 8601 last update timestamp

List Reports

GET https://api.weellu.com/api/v1/report-system

Returns all submitted reports, ordered by newest first.

Parameters

No parameters required.

Example Request

curl "https://api.weellu.com/api/v1/report-system" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/report-system",
  {
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/report-system',
);

Example Response

[
  {
    "_id": "660f6a7b8c9d0e1f2a3b4c5d",
    "content": "App crashes when opening group chat with 100+ members",
    "stack": "Error: RangeError (index): Invalid value...",
    "type": "crash",
    "platform": "android",
    "uId": "659f1a2b3c4d5e6f7a8b9c0d",
    "createdAt": "2026-03-18T10:30:00.000Z",
    "updatedAt": "2026-03-18T10:30:00.000Z"
  },
  {
    "_id": "660f6a7b8c9d0e1f2a3b4c5e",
    "content": "Voice messages not playing on iOS 17",
    "stack": "AVAudioPlayer error: -11800",
    "type": "bug",
    "platform": "ios",
    "uId": "659f2b3c4d5e6f7a8b9c0d1e",
    "createdAt": "2026-03-17T15:00:00.000Z",
    "updatedAt": "2026-03-17T15:00:00.000Z"
  }
]

S3 Upload

Generate presigned URLs for direct file uploads to S3 storage. This is the standard single-file upload mechanism for chat attachments and story media.

Create Presigned Upload URL

POST https://api.weellu.com/api/v1/s3

Creates a presigned S3 URL that allows the client to upload a file directly to cloud storage without routing the binary through the API server.

Body Parameters

Parameter Type Required Description
uploadType string Yes The upload context. One of: chat, story
identifier string Yes A UUID v4 identifier for the upload, used as part of the S3 key
fileName string Yes Original file name including extension (e.g., photo.jpg)

Example Request

curl -X POST "https://api.weellu.com/api/v1/s3" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "uploadType": "chat",
    "identifier": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "fileName": "vacation_photo.jpg"
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/s3",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_JWT_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      uploadType: "chat",
      identifier: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      fileName: "vacation_photo.jpg",
    }),
  }
);
const data = await response.json();
import 'package:uuid/uuid.dart';

final response = await chopper.post(
  '/api/v1/s3',
  body: {
    'uploadType': 'chat',
    'identifier': const Uuid().v4(),
    'fileName': 'vacation_photo.jpg',
  },
);

Example Response

{
  "code": 200,
  "data": {
    "presignedUrl": "https://weellu-bucket.s3.amazonaws.com/chat/659f1a2b/f47ac10b-58cc-4372-a567-0e02b2c3d479/vacation_photo.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...",
    "fileUrl": "https://weellu-bucket.s3.amazonaws.com/chat/659f1a2b/f47ac10b-58cc-4372-a567-0e02b2c3d479/vacation_photo.jpg"
  }
}

Response Fields

Field Type Description
presignedUrl string Temporary S3 URL for uploading the file via HTTP PUT. Expires after a set time
fileUrl string The permanent URL where the file will be accessible after upload

Multipart Upload

For large files, use multipart upload to split files into chunks and upload them in parallel. This provides resumability and better reliability for large media transfers.

Initiate Multipart Upload

POST https://api.weellu.com/api/v1/multipart-upload/initiate

Starts a new multipart upload session. The server creates an S3 multipart upload and returns presigned URLs for each part. The response includes chunk metadata so the client knows exactly which bytes to upload for each part.

Body Parameters

Parameter Type Required Description
localId string Yes Client-side unique identifier for the upload (used for deduplication and resume)
fileName string Yes Original file name including extension
fileSize number Yes Total file size in bytes. Must be at least 1
mimeType string Yes MIME type of the file (e.g., video/mp4, image/png)
fileHash string Yes Hash of the complete file for integrity verification
chunks array Yes Array of chunk descriptor objects defining how the file is split
chunks[].partNumber number Yes Sequential part number for this chunk
chunks[].size number Yes Size of this chunk in bytes. Must be at least 1
chunks[].startByte number Yes Starting byte offset in the original file (0-indexed)
chunks[].endByte number Yes Ending byte offset in the original file (0-indexed)
chunks[].md5 string Yes MD5 hash of this chunk for per-part integrity verification
metadata object No Optional key-value metadata to attach to the upload

Example Request

curl -X POST "https://api.weellu.com/api/v1/multipart-upload/initiate" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "localId": "upload-abc-123",
    "fileName": "large_video.mp4",
    "fileSize": 52428800,
    "mimeType": "video/mp4",
    "fileHash": "d41d8cd98f00b204e9800998ecf8427e",
    "chunks": [
      {
        "partNumber": 1,
        "size": 10485760,
        "startByte": 0,
        "endByte": 10485759,
        "md5": "a1b2c3d4e5f6a7b8c9d0e1f2"
      },
      {
        "partNumber": 2,
        "size": 10485760,
        "startByte": 10485760,
        "endByte": 20971519,
        "md5": "b2c3d4e5f6a7b8c9d0e1f2a3"
      },
      {
        "partNumber": 3,
        "size": 10485760,
        "startByte": 20971520,
        "endByte": 31457279,
        "md5": "c3d4e5f6a7b8c9d0e1f2a3b4"
      },
      {
        "partNumber": 4,
        "size": 10485760,
        "startByte": 31457280,
        "endByte": 41943039,
        "md5": "d4e5f6a7b8c9d0e1f2a3b4c5"
      },
      {
        "partNumber": 5,
        "size": 10485760,
        "startByte": 41943040,
        "endByte": 52428799,
        "md5": "e5f6a7b8c9d0e1f2a3b4c5d6"
      }
    ],
    "metadata": {
      "roomId": "660d4e5f6a7b8c9d0e1f2a3b",
      "messageType": "video"
    }
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/multipart-upload/initiate",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_JWT_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      localId: "upload-abc-123",
      fileName: "large_video.mp4",
      fileSize: 52428800,
      mimeType: "video/mp4",
      fileHash: "d41d8cd98f00b204e9800998ecf8427e",
      chunks: [
        { partNumber: 1, size: 10485760, startByte: 0, endByte: 10485759, md5: "a1b2c3d4e5f6a7b8c9d0e1f2" },
        { partNumber: 2, size: 10485760, startByte: 10485760, endByte: 20971519, md5: "b2c3d4e5f6a7b8c9d0e1f2a3" },
      ],
      metadata: { roomId: "660d4e5f6a7b8c9d0e1f2a3b" },
    }),
  }
);
const data = await response.json();
final response = await chopper.post(
  '/api/v1/multipart-upload/initiate',
  body: {
    'localId': 'upload-abc-123',
    'fileName': 'large_video.mp4',
    'fileSize': 52428800,
    'mimeType': 'video/mp4',
    'fileHash': 'd41d8cd98f00b204e9800998ecf8427e',
    'chunks': [
      {'partNumber': 1, 'size': 10485760, 'startByte': 0, 'endByte': 10485759, 'md5': 'a1b2c3d4e5f6a7b8c9d0e1f2'},
      {'partNumber': 2, 'size': 10485760, 'startByte': 10485760, 'endByte': 20971519, 'md5': 'b2c3d4e5f6a7b8c9d0e1f2a3'},
    ],
  },
);

Example Response

{
  "code": 201,
  "data": {
    "sessionId": "660f7b8c9d0e1f2a3b4c5d6e",
    "uploadId": "VXBsb2FkSWQ_example_abc123",
    "totalParts": 5,
    "presignedUrls": [
      {
        "partNumber": 1,
        "url": "https://weellu-bucket.s3.amazonaws.com/uploads/660f7b8c/part1?X-Amz-Algorithm=...",
        "partSize": 10485760,
        "expiresIn": 3600
      },
      {
        "partNumber": 2,
        "url": "https://weellu-bucket.s3.amazonaws.com/uploads/660f7b8c/part2?X-Amz-Algorithm=...",
        "partSize": 10485760,
        "expiresIn": 3600
      }
    ],
    "resumeInfo": null
  }
}

Response Fields

Field Type Description
sessionId string Server-side session ID for this upload. Used in all subsequent calls
uploadId string S3 multipart upload ID
totalParts number Total number of parts expected
presignedUrls array Array of presigned URL objects for each part
presignedUrls[].partNumber number Part number this URL is for
presignedUrls[].url string Presigned S3 URL for uploading this part via HTTP PUT
presignedUrls[].partSize number Expected size in bytes for this part
presignedUrls[].expiresIn number Time in seconds until the presigned URL expires
resumeInfo object Present when resuming a previously started upload. Nullable
resumeInfo.uploadedParts number[] Part numbers that have already been uploaded
resumeInfo.remainingParts number[] Part numbers still pending upload

Get Presigned URL for Part

POST https://api.weellu.com/api/v1/multipart-upload/part/presigned-url

Generates a fresh presigned URL for a specific part. Use this when a previously issued presigned URL has expired or when you need to retry a failed part upload.

Body Parameters

Parameter Type Required Description
sessionId string Yes The upload session ID (MongoDB ObjectId)
partNumber number Yes The part number to generate a URL for. Range: 1-10000

Example Request

curl -X POST "https://api.weellu.com/api/v1/multipart-upload/part/presigned-url" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "sessionId": "660f7b8c9d0e1f2a3b4c5d6e",
    "partNumber": 3
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/multipart-upload/part/presigned-url",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_JWT_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      sessionId: "660f7b8c9d0e1f2a3b4c5d6e",
      partNumber: 3,
    }),
  }
);
const data = await response.json();
final response = await chopper.post(
  '/api/v1/multipart-upload/part/presigned-url',
  body: {
    'sessionId': '660f7b8c9d0e1f2a3b4c5d6e',
    'partNumber': 3,
  },
);

Example Response

{
  "code": 200,
  "data": {
    "presignedUrl": "https://weellu-bucket.s3.amazonaws.com/uploads/660f7b8c/part3?X-Amz-Algorithm=...",
    "partNumber": 3,
    "partSize": 10485760,
    "expiresIn": 3600,
    "isUploaded": false,
    "etag": null,
    "message": null
  }
}

Response Fields

Field Type Description
presignedUrl string Presigned S3 URL for uploading this part. Nullable if part already uploaded
partNumber number The requested part number
partSize number Expected size in bytes for this part. Nullable
expiresIn number Time in seconds until the URL expires. Nullable
isUploaded boolean Whether this part has already been successfully uploaded. Nullable
etag string The ETag of the part if already uploaded. Nullable
message string Informational message (e.g., "Part already uploaded"). Nullable

Complete Part Upload

POST https://api.weellu.com/api/v1/multipart-upload/part/complete

Marks a specific part as successfully uploaded. The client must call this after uploading each part to S3.

Body Parameters

Parameter Type Required Description
sessionId string Yes The upload session ID (MongoDB ObjectId)
partNumber number Yes The part number that was uploaded. Range: 1-10000
etag string Yes The ETag returned by S3 in the PUT response header
md5 string Yes MD5 hash of the uploaded part for integrity verification

Example Request

curl -X POST "https://api.weellu.com/api/v1/multipart-upload/part/complete" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "sessionId": "660f7b8c9d0e1f2a3b4c5d6e",
    "partNumber": 1,
    "etag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
    "md5": "a1b2c3d4e5f6a7b8c9d0e1f2"
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/multipart-upload/part/complete",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_JWT_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      sessionId: "660f7b8c9d0e1f2a3b4c5d6e",
      partNumber: 1,
      etag: '"d41d8cd98f00b204e9800998ecf8427e"',
      md5: "a1b2c3d4e5f6a7b8c9d0e1f2",
    }),
  }
);
const data = await response.json();
final response = await chopper.post(
  '/api/v1/multipart-upload/part/complete',
  body: {
    'sessionId': '660f7b8c9d0e1f2a3b4c5d6e',
    'partNumber': 1,
    'etag': '"d41d8cd98f00b204e9800998ecf8427e"',
    'md5': 'a1b2c3d4e5f6a7b8c9d0e1f2',
  },
);

Example Response

{
  "code": 200,
  "data": {
    "success": true,
    "remainingParts": [2, 3, 4, 5]
  }
}

Response Fields

Field Type Description
success boolean Whether the part was marked as complete
remainingParts number[] Array of part numbers still pending upload

Complete Multipart Upload

POST https://api.weellu.com/api/v1/multipart-upload/complete

Finalizes the multipart upload after all parts have been uploaded and confirmed. This triggers S3 to assemble the parts into the final file.

Body Parameters

Parameter Type Required Description
sessionId string Yes The upload session ID (MongoDB ObjectId)

Example Request

curl -X POST "https://api.weellu.com/api/v1/multipart-upload/complete" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "sessionId": "660f7b8c9d0e1f2a3b4c5d6e"
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/multipart-upload/complete",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_JWT_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      sessionId: "660f7b8c9d0e1f2a3b4c5d6e",
    }),
  }
);
const data = await response.json();
final response = await chopper.post(
  '/api/v1/multipart-upload/complete',
  body: {
    'sessionId': '660f7b8c9d0e1f2a3b4c5d6e',
  },
);

Example Response

{
  "code": 200,
  "data": {
    "success": true,
    "fileUrl": "https://weellu-bucket.s3.amazonaws.com/uploads/660f7b8c/large_video.mp4",
    "key": "uploads/660f7b8c/large_video.mp4"
  }
}

Response Fields

Field Type Description
success boolean Whether the upload was finalized successfully
fileUrl string The permanent URL where the assembled file is accessible
key string The S3 object key for the file

Abort Multipart Upload

DELETE https://api.weellu.com/api/v1/multipart-upload/abort/:sessionId

Aborts an in-progress multipart upload. This cleans up any uploaded parts from S3 and marks the session as aborted. Cannot be used on already-completed uploads.

Path Parameters

Parameter Type Required Description
sessionId string Yes The upload session ID

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/multipart-upload/abort/660f7b8c9d0e1f2a3b4c5d6e" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/multipart-upload/abort/660f7b8c9d0e1f2a3b4c5d6e",
  {
    method: "DELETE",
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/api/v1/multipart-upload/abort/660f7b8c9d0e1f2a3b4c5d6e',
);

Example Response

{
  "code": 200,
  "data": {
    "success": true,
    "message": "Upload aborted successfully"
  }
}

Response Fields

Field Type Description
success boolean Whether the upload was aborted
message string Human-readable confirmation message

Bot

Manage project bots and bot forms. Bots provide automated question-and-answer trees within project rooms.

Bot Form

Bot forms associate a bot configuration with a specific chat room and user pairing.

Create Bot Form

POST https://api.weellu.com/api/v1/bot-form

Creates a new bot form linking two users and a room. Accepts an optional image file via multipart form data.

Body Parameters (multipart/form-data)

Parameter Type Required Description
firstId string Yes First user ID (MongoDB ObjectId)
lastId string Yes Second user ID (MongoDB ObjectId)
roomId string Yes Chat room ID (MongoDB ObjectId)
file file No Optional image file for the bot form

Example Request

curl -X POST "https://api.weellu.com/api/v1/bot-form" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -F "firstId=659f1a2b3c4d5e6f7a8b9c0d" \
  -F "lastId=659f2b3c4d5e6f7a8b9c0d1e" \
  -F "roomId=660d4e5f6a7b8c9d0e1f2a3b" \
  -F "file=@bot_avatar.png"
const formData = new FormData();
formData.append("firstId", "659f1a2b3c4d5e6f7a8b9c0d");
formData.append("lastId", "659f2b3c4d5e6f7a8b9c0d1e");
formData.append("roomId", "660d4e5f6a7b8c9d0e1f2a3b");
formData.append("file", imageFile);

const response = await fetch(
  "https://api.weellu.com/api/v1/bot-form",
  {
    method: "POST",
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
    body: formData,
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/bot-form'),
);
request.headers['Authorization'] = 'Bearer YOUR_JWT_TOKEN';
request.fields['firstId'] = '659f1a2b3c4d5e6f7a8b9c0d';
request.fields['lastId'] = '659f2b3c4d5e6f7a8b9c0d1e';
request.fields['roomId'] = '660d4e5f6a7b8c9d0e1f2a3b';
request.files.add(await http.MultipartFile.fromPath('file', 'bot_avatar.png'));
final response = await request.send();

Example Response

{
  "_id": "661a2b3c4d5e6f7a8b9c0d1e",
  "firstId": "659f1a2b3c4d5e6f7a8b9c0d",
  "lastId": "659f2b3c4d5e6f7a8b9c0d1e",
  "roomId": "660d4e5f6a7b8c9d0e1f2a3b",
  "image": "https://weellu-bucket.s3.amazonaws.com/bots/661a2b3c/avatar.png",
  "createdAt": "2026-03-18T10:30:00.000Z"
}

Get Bot Form

GET https://api.weellu.com/api/v1/bot-form

Retrieves a bot form by peer ID and room ID.

Query Parameters

Parameter Type Required Description
peerId string Yes The peer user's ID (MongoDB ObjectId)
roomId string Yes The chat room ID (MongoDB ObjectId)

Example Request

curl "https://api.weellu.com/api/v1/bot-form?peerId=659f2b3c4d5e6f7a8b9c0d1e&roomId=660d4e5f6a7b8c9d0e1f2a3b" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/bot-form?peerId=659f2b3c4d5e6f7a8b9c0d1e&roomId=660d4e5f6a7b8c9d0e1f2a3b",
  {
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/bot-form',
  parameters: {
    'peerId': '659f2b3c4d5e6f7a8b9c0d1e',
    'roomId': '660d4e5f6a7b8c9d0e1f2a3b',
  },
);

Example Response

{
  "_id": "661a2b3c4d5e6f7a8b9c0d1e",
  "firstId": "659f1a2b3c4d5e6f7a8b9c0d",
  "lastId": "659f2b3c4d5e6f7a8b9c0d1e",
  "roomId": "660d4e5f6a7b8c9d0e1f2a3b",
  "image": "https://weellu-bucket.s3.amazonaws.com/bots/661a2b3c/avatar.png",
  "createdAt": "2026-03-18T10:30:00.000Z"
}

Get Connected Project

GET https://api.weellu.com/api/v1/bot-form/get-connected-project/:id

Retrieves the project connected to a bot form.

Path Parameters

Parameter Type Required Description
id string Yes The bot form ID (MongoDB ObjectId)

Example Request

curl "https://api.weellu.com/api/v1/bot-form/get-connected-project/661a2b3c4d5e6f7a8b9c0d1e" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/bot-form/get-connected-project/661a2b3c4d5e6f7a8b9c0d1e",
  {
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/bot-form/get-connected-project/661a2b3c4d5e6f7a8b9c0d1e',
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "660d4e5f6a7b8c9d0e1f2a3b",
    "name": "Project Alpha",
    "image": "https://weellu-bucket.s3.amazonaws.com/projects/alpha.png"
  }
}

Get My Bot Form

GET https://api.weellu.com/api/v1/bot-form/get-my-form

Retrieves the authenticated user's own bot form configuration.

Parameters

No parameters required.

Example Request

curl "https://api.weellu.com/api/v1/bot-form/get-my-form" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/bot-form/get-my-form",
  {
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/bot-form/get-my-form',
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "661a2b3c4d5e6f7a8b9c0d1e",
    "firstId": "659f1a2b3c4d5e6f7a8b9c0d",
    "lastId": "659f2b3c4d5e6f7a8b9c0d1e",
    "roomId": "660d4e5f6a7b8c9d0e1f2a3b",
    "image": "https://weellu-bucket.s3.amazonaws.com/bots/661a2b3c/avatar.png",
    "createdAt": "2026-03-18T10:30:00.000Z"
  }
}

Update Bot Form Image

PATCH https://api.weellu.com/api/v1/bot-form

Updates the image of the authenticated user's bot form.

Body Parameters (multipart/form-data)

Parameter Type Required Description
file file Yes New image file for the bot form

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/bot-form" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -F "file=@new_avatar.png"
const formData = new FormData();
formData.append("file", newImageFile);

const response = await fetch(
  "https://api.weellu.com/api/v1/bot-form",
  {
    method: "PATCH",
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
    body: formData,
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'PATCH',
  Uri.parse('https://api.weellu.com/api/v1/bot-form'),
);
request.headers['Authorization'] = 'Bearer YOUR_JWT_TOKEN';
request.files.add(await http.MultipartFile.fromPath('file', 'new_avatar.png'));
final response = await request.send();

Example Response

{
  "code": 200,
  "data": {
    "_id": "661a2b3c4d5e6f7a8b9c0d1e",
    "image": "https://weellu-bucket.s3.amazonaws.com/bots/661a2b3c/new_avatar.png"
  }
}

Project Bot

Manage the question-and-answer tree for project bots. Bot questions form a hierarchical menu that users can navigate.

Get Bot Questions

GET https://api.weellu.com/api/v1/profile/project/bot/question

Returns a list of bot questions. Use isParentIdNull=true to get top-level menu items.

Query Parameters

Parameter Type Required Description
isParentIdNull string No If "true", returns only top-level questions (menu items). Boolean string
userId string No Filter questions by a specific user ID (MongoDB ObjectId)
sort string No Sort field and direction (e.g., "-createdAt" for newest first)

Example Request

curl "https://api.weellu.com/api/v1/profile/project/bot/question?isParentIdNull=true" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/profile/project/bot/question?isParentIdNull=true",
  {
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/profile/project/bot/question',
  parameters: {'isParentIdNull': 'true'},
);

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "661b3c4d5e6f7a8b9c0d1e2f",
      "content": "How can I help you?",
      "description": "Main menu for customer support",
      "icon": "help_outline",
      "image": null,
      "parentId": null,
      "createdAt": "2026-03-18T10:30:00.000Z"
    },
    {
      "_id": "661b3c4d5e6f7a8b9c0d1e30",
      "content": "Pricing Information",
      "description": "View our pricing plans",
      "icon": "attach_money",
      "image": "https://weellu-bucket.s3.amazonaws.com/bots/pricing.png",
      "parentId": null,
      "createdAt": "2026-03-18T09:00:00.000Z"
    }
  ]
}

Get Single Bot Question

GET https://api.weellu.com/api/v1/profile/project/bot/one

Returns a single bot question by ID, or the root question if no ID is provided.

Query Parameters

Parameter Type Required Description
id string No The question ID (MongoDB ObjectId). If omitted, returns the root question

Example Request

curl "https://api.weellu.com/api/v1/profile/project/bot/one?id=661b3c4d5e6f7a8b9c0d1e2f" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/profile/project/bot/one?id=661b3c4d5e6f7a8b9c0d1e2f",
  {
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/profile/project/bot/one',
  parameters: {'id': '661b3c4d5e6f7a8b9c0d1e2f'},
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "661b3c4d5e6f7a8b9c0d1e2f",
    "content": "How can I help you?",
    "description": "Main menu for customer support",
    "icon": "help_outline",
    "image": null,
    "parentId": null,
    "createdAt": "2026-03-18T10:30:00.000Z"
  }
}

Create Bot Question

POST https://api.weellu.com/api/v1/profile/project/bot/question

Creates a new top-level bot question (menu item). Accepts an optional image file via multipart form data.

Body Parameters (multipart/form-data)

Parameter Type Required Description
content string Yes The question or menu item text
parentId string No Parent question ID to create a nested question (MongoDB ObjectId)
description string No Additional description or help text
icon string No Icon identifier for the question
file file No Optional image file

Example Request

curl -X POST "https://api.weellu.com/api/v1/profile/project/bot/question" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -F "content=What are your business hours?" \
  -F "description=Operating hours and availability" \
  -F "icon=schedule"
const formData = new FormData();
formData.append("content", "What are your business hours?");
formData.append("description", "Operating hours and availability");
formData.append("icon", "schedule");

const response = await fetch(
  "https://api.weellu.com/api/v1/profile/project/bot/question",
  {
    method: "POST",
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
    body: formData,
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/profile/project/bot/question'),
);
request.headers['Authorization'] = 'Bearer YOUR_JWT_TOKEN';
request.fields['content'] = 'What are your business hours?';
request.fields['description'] = 'Operating hours and availability';
request.fields['icon'] = 'schedule';
final response = await request.send();

Example Response

{
  "code": 200,
  "data": {
    "_id": "661c4d5e6f7a8b9c0d1e2f3a",
    "content": "What are your business hours?",
    "description": "Operating hours and availability",
    "icon": "schedule",
    "image": null,
    "parentId": null,
    "createdAt": "2026-03-18T11:00:00.000Z"
  }
}

Create Bot Answer

POST https://api.weellu.com/api/v1/profile/project/bot/answer/:id

Creates an answer (child node) under an existing bot question.

Path Parameters

Parameter Type Required Description
id string Yes The parent question ID (MongoDB ObjectId)

Body Parameters (multipart/form-data)

Parameter Type Required Description
content string Yes The answer text
description string No Additional description
icon string No Icon identifier
file file No Optional image file

Example Request

curl -X POST "https://api.weellu.com/api/v1/profile/project/bot/answer/661b3c4d5e6f7a8b9c0d1e2f" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -F "content=We are open Monday-Friday, 9AM-6PM EST"
const formData = new FormData();
formData.append("content", "We are open Monday-Friday, 9AM-6PM EST");

const response = await fetch(
  "https://api.weellu.com/api/v1/profile/project/bot/answer/661b3c4d5e6f7a8b9c0d1e2f",
  {
    method: "POST",
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
    body: formData,
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/profile/project/bot/answer/661b3c4d5e6f7a8b9c0d1e2f'),
);
request.headers['Authorization'] = 'Bearer YOUR_JWT_TOKEN';
request.fields['content'] = 'We are open Monday-Friday, 9AM-6PM EST';
final response = await request.send();

Example Response

{
  "code": 200,
  "data": {
    "_id": "661d5e6f7a8b9c0d1e2f3a4b",
    "content": "We are open Monday-Friday, 9AM-6PM EST",
    "description": null,
    "icon": null,
    "image": null,
    "parentId": "661b3c4d5e6f7a8b9c0d1e2f",
    "createdAt": "2026-03-18T11:30:00.000Z"
  }
}

Update Bot Question

PATCH https://api.weellu.com/api/v1/profile/project/bot/:id

Updates an existing bot question or answer. Supports updating content, description, status, and image.

Path Parameters

Parameter Type Required Description
id string Yes The question/answer ID (MongoDB ObjectId)

Body Parameters (multipart/form-data)

Parameter Type Required Description
content string No Updated question/answer text
description string No Updated description
status string No Bot text status (enum value)
file file No New image file

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/profile/project/bot/661b3c4d5e6f7a8b9c0d1e2f" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -F "content=Updated: How can we assist you today?" \
  -F "description=Updated main menu"
const formData = new FormData();
formData.append("content", "Updated: How can we assist you today?");
formData.append("description", "Updated main menu");

const response = await fetch(
  "https://api.weellu.com/api/v1/profile/project/bot/661b3c4d5e6f7a8b9c0d1e2f",
  {
    method: "PATCH",
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
    body: formData,
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'PATCH',
  Uri.parse('https://api.weellu.com/api/v1/profile/project/bot/661b3c4d5e6f7a8b9c0d1e2f'),
);
request.headers['Authorization'] = 'Bearer YOUR_JWT_TOKEN';
request.fields['content'] = 'Updated: How can we assist you today?';
request.fields['description'] = 'Updated main menu';
final response = await request.send();

Example Response

{
  "code": 200,
  "data": {
    "_id": "661b3c4d5e6f7a8b9c0d1e2f",
    "content": "Updated: How can we assist you today?",
    "description": "Updated main menu",
    "icon": "help_outline",
    "image": null,
    "parentId": null,
    "createdAt": "2026-03-18T10:30:00.000Z"
  }
}

Delete Bot Question

DELETE https://api.weellu.com/api/v1/profile/project/bot/:id

Deletes a bot question or answer. If the question has child answers, they may also be removed.

Path Parameters

Parameter Type Required Description
id string Yes The question/answer ID (MongoDB ObjectId)

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/profile/project/bot/661b3c4d5e6f7a8b9c0d1e2f" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/profile/project/bot/661b3c4d5e6f7a8b9c0d1e2f",
  {
    method: "DELETE",
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/api/v1/profile/project/bot/661b3c4d5e6f7a8b9c0d1e2f',
);

Example Response

{
  "code": 200,
  "data": {
    "message": "Question deleted successfully"
  }
}

Marketplace

Browse the Weellu marketplace, discover products, and explore categories.

Get Market Home

GET https://api.weellu.com/api/v1/market/home

Returns the marketplace home page data including featured products, highlights, and promotional content.

Parameters

No parameters required.

Example Request

curl "https://api.weellu.com/api/v1/market/home" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/market/home",
  {
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/market/home',
);

Example Response

{
  "code": 200,
  "data": {
    "banners": [
      {
        "_id": "661e6f7a8b9c0d1e2f3a4b5c",
        "imageUrl": "https://weellu-bucket.s3.amazonaws.com/banners/spring_sale.jpg",
        "redirectUrl": "https://weellu.com/market/sale",
        "order": 0
      }
    ],
    "highlights": [
      {
        "_id": "661f7a8b9c0d1e2f3a4b5c6d",
        "title": "Latest Electronics",
        "products": [
          {
            "_id": "66207b8c9d0e1f2a3b4c5d6e",
            "title": "Wireless Headphones",
            "price": 79.99,
            "priceUnit": "USD",
            "images": ["https://weellu-bucket.s3.amazonaws.com/products/headphones.jpg"]
          }
        ]
      }
    ],
    "categories": [
      {
        "_id": "66218c9d0e1f2a3b4c5d6e7f",
        "name": "Electronics",
        "icon": "devices",
        "iconColor": "#2196F3"
      }
    ]
  }
}

Get More Highlights

GET https://api.weellu.com/api/v1/market/more/highlight

Returns additional highlight sections with pagination for the marketplace.

Query Parameters

Parameter Type Required Description
page number No Page number for pagination
limit number No Number of highlights per page

Example Request

curl "https://api.weellu.com/api/v1/market/more/highlight?page=1&limit=10" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/market/more/highlight?page=1&limit=10",
  {
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/market/more/highlight',
  parameters: {'page': 1, 'limit': 10},
);

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "661f7a8b9c0d1e2f3a4b5c6d",
      "title": "Trending Now",
      "products": [
        {
          "_id": "66207b8c9d0e1f2a3b4c5d6e",
          "title": "Smart Watch",
          "price": 199.99,
          "priceUnit": "USD",
          "images": ["https://weellu-bucket.s3.amazonaws.com/products/watch.jpg"]
        }
      ]
    }
  ]
}

Get Categories

GET https://api.weellu.com/api/v1/market/category

Returns a list of marketplace product categories.

Query Parameters

Parameter Type Required Description
page number No Page number for pagination
limit number No Number of categories per page

Example Request

curl "https://api.weellu.com/api/v1/market/category" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/market/category",
  {
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/market/category',
);

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "66218c9d0e1f2a3b4c5d6e7f",
      "name": "Electronics",
      "icon": "devices",
      "iconColor": "#2196F3",
      "parentId": null
    },
    {
      "_id": "66219d0e1f2a3b4c5d6e7f8a",
      "name": "Smartphones",
      "icon": "smartphone",
      "iconColor": "#4CAF50",
      "parentId": "66218c9d0e1f2a3b4c5d6e7f"
    },
    {
      "_id": "6621ae1f2a3b4c5d6e7f8a9b",
      "name": "Fashion",
      "icon": "checkroom",
      "iconColor": "#E91E63",
      "parentId": null
    }
  ]
}

Response Fields

Field Type Description
_id string Category ID
name string Category display name
icon string Icon identifier
iconColor string Hex color code for the icon
parentId string Parent category ID for subcategories. Null for top-level categories

Get Category Attributes

GET https://api.weellu.com/api/v1/market/attribute/:id

Returns the attribute definitions for a specific category. Attributes define the filterable properties of products in that category (e.g., screen size for electronics, fabric type for clothing).

Path Parameters

Parameter Type Required Description
id string Yes The category ID (MongoDB ObjectId)

Example Request

curl "https://api.weellu.com/api/v1/market/attribute/66218c9d0e1f2a3b4c5d6e7f" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/market/attribute/66218c9d0e1f2a3b4c5d6e7f",
  {
    headers: { Authorization: "Bearer YOUR_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/market/attribute/66218c9d0e1f2a3b4c5d6e7f',
);

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "6622bf2a3b4c5d6e7f8a9b0c",
      "name": "Screen Size",
      "type": "select",
      "options": ["5.5\"", "6.1\"", "6.7\""],
      "categoryId": "66218c9d0e1f2a3b4c5d6e7f",
      "required": true
    },
    {
      "_id": "6622c03b4c5d6e7f8a9b0c1d",
      "name": "Storage",
      "type": "select",
      "options": ["64GB", "128GB", "256GB", "512GB"],
      "categoryId": "66218c9d0e1f2a3b4c5d6e7f",
      "required": true
    },
    {
      "_id": "6622c14c5d6e7f8a9b0c1d2e",
      "name": "Color",
      "type": "text",
      "options": [],
      "categoryId": "66218c9d0e1f2a3b4c5d6e7f",
      "required": false
    }
  ]
}

Response Fields

Field Type Description
_id string Attribute ID
name string Attribute display name
type string Input type (e.g., select, text, number)
options array Available options for select-type attributes
categoryId string The category this attribute belongs to
required boolean Whether this attribute is required when creating a product

Admin Panel

Admin Login

POST https://api.weellu.com/api/v1/admin-panel/login

Authenticates an admin user and validates their SuperAdmin privileges. The Bearer token used must already belong to a SuperAdmin account.

Parameters

No body parameters required. Authentication is performed via the Bearer token.

Example Request

curl -X POST "https://api.weellu.com/api/v1/admin-panel/login" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/login",
  {
    method: "POST",
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.post(
  '/api/v1/admin-panel/login',
);

Example Response

{
  "code": 200,
  "data": {
    "message": "Login successful",
    "role": "superAdmin"
  }
}

Get Dashboard

GET https://api.weellu.com/api/v1/admin-panel/dashboard

Returns platform-wide dashboard statistics including user counts, message counts, and system health metrics.

Parameters

No parameters required.

Example Request

curl "https://api.weellu.com/api/v1/admin-panel/dashboard" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/dashboard",
  {
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/admin-panel/dashboard',
);

Example Response

{
  "code": 200,
  "data": {
    "totalUsers": 15420,
    "activeUsers": 8730,
    "totalRooms": 45200,
    "totalMessages": 1250000,
    "onlineUsers": 342,
    "registeredToday": 28
  }
}

Response Fields

Field Type Description
totalUsers number Total registered users on the platform
activeUsers number Users who have been active recently
totalRooms number Total chat rooms created
totalMessages number Total messages sent across the platform
onlineUsers number Currently connected users
registeredToday number Users who registered today

Get Message Count

GET https://api.weellu.com/api/v1/admin-panel/message-count

Returns message count statistics filtered by a time period.

Query Parameters

Parameter Type Required Description
filter string No Time filter. One of the DashMessagesCountEnum values (e.g., today, week, month, year)

Example Request

curl "https://api.weellu.com/api/v1/admin-panel/message-count?filter=week" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/message-count?filter=week",
  {
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/admin-panel/message-count',
  parameters: {'filter': 'week'},
);

Example Response

{
  "code": 200,
  "data": {
    "count": 42500,
    "filter": "week"
  }
}

Get App Config

GET https://api.weellu.com/api/v1/admin-panel/config

Returns the current application configuration.

Parameters

No parameters required.

Example Request

curl "https://api.weellu.com/api/v1/admin-panel/config" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/config",
  {
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/admin-panel/config',
);

Example Response

{
  "code": 200,
  "data": {
    "configVersion": 12,
    "clintVersion": "2.5.0",
    "backendVersion": "3.1.0",
    "enableAds": false,
    "approveMessage": "Your account has been approved!",
    "pendingMessage": "Your account is pending review.",
    "userIcon": "https://weellu-bucket.s3.amazonaws.com/defaults/user.png",
    "feedbackEmail": "support@weellu.com",
    "shareAppMessage": "Check out Weellu - the best communication platform!",
    "allowWebLogin": true,
    "allowMobileLogin": true,
    "allowCreateGroup": true,
    "allowCreateBroadcast": true,
    "allowDesktopLogin": true,
    "privacyUrl": "https://weellu.com/privacy",
    "googlePayUrl": "https://play.google.com/store/apps/details?id=com.weellu",
    "appleStoreUrl": "https://apps.apple.com/app/weellu/id123456789",
    "maxExpireEmailTime": 300,
    "userRegisterStatus": "approved",
    "callTimeout": 30000,
    "maxGroupMembers": 512,
    "maxBroadcastMembers": 1024,
    "maxChatMediaSize": 104857600,
    "allowCall": true,
    "groupIcon": "https://weellu-bucket.s3.amazonaws.com/defaults/group.png",
    "supportIcon": "https://weellu-bucket.s3.amazonaws.com/defaults/support.png",
    "broadcastIcon": "https://weellu-bucket.s3.amazonaws.com/defaults/broadcast.png"
  }
}

Update App Config

PATCH https://api.weellu.com/api/v1/admin-panel/config

Updates the application configuration. All fields are optional; only provided fields are updated.

Body Parameters

Parameter Type Required Description
configVersion number No Configuration version number
clintVersion string No Minimum required client version
backendVersion string No Current backend version
enableAds boolean No Whether advertisements are enabled
approveMessage string No Message shown when user account is approved
pendingMessage string No Message shown when user account is pending
userIcon string No Default user avatar URL
feedbackEmail string No Support/feedback email address
shareAppMessage string No Message used when sharing the app
allowWebLogin boolean No Whether web login is allowed
allowMobileLogin boolean No Whether mobile login is allowed
allowCreateGroup boolean No Whether users can create groups
allowCreateBroadcast boolean No Whether users can create broadcasts
allowDesktopLogin boolean No Whether desktop login is allowed
privacyUrl string No Privacy policy URL
googlePayUrl string No Google Play Store URL
appleStoreUrl string No Apple App Store URL
maxExpireEmailTime number No Email verification code expiry time in seconds
userRegisterStatus string No Default registration status. One of: approved, pending, blocked
callTimeout number No Call ring timeout in milliseconds
maxGroupMembers number No Maximum members allowed in a group
maxBroadcastMembers number No Maximum members allowed in a broadcast
maxChatMediaSize number No Maximum media file size in bytes
allowCall boolean No Whether voice/video calls are enabled
groupIcon string No Default group avatar URL
supportIcon string No Default support avatar URL
broadcastIcon string No Default broadcast avatar URL

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/admin-panel/config" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "enableAds": true,
    "maxGroupMembers": 1024,
    "allowCall": true
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/config",
  {
    method: "PATCH",
    headers: {
      Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      enableAds: true,
      maxGroupMembers: 1024,
      allowCall: true,
    }),
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/api/v1/admin-panel/config',
  body: {
    'enableAds': true,
    'maxGroupMembers': 1024,
    'allowCall': true,
  },
);

Example Response

{
  "code": 200,
  "data": {
    "configVersion": 13,
    "enableAds": true,
    "maxGroupMembers": 1024,
    "allowCall": true
  }
}

Get Users

GET https://api.weellu.com/api/v1/admin-panel/users

Returns a paginated list of all platform users with filtering options.

Query Parameters

Parameter Type Required Description
page number No Page number
limit number No Users per page
search string No Search by name or email

Example Request

curl "https://api.weellu.com/api/v1/admin-panel/users?page=1&limit=20" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/users?page=1&limit=20",
  {
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/admin-panel/users',
  parameters: {'page': 1, 'limit': 20},
);

Example Response

{
  "code": 200,
  "data": {
    "docs": [
      {
        "_id": "659f1a2b3c4d5e6f7a8b9c0d",
        "fullName": "John Doe",
        "email": "john@example.com",
        "registerStatus": "approved",
        "createdAt": "2026-01-15T08:00:00.000Z"
      }
    ],
    "totalDocs": 15420,
    "limit": 20,
    "page": 1,
    "totalPages": 771
  }
}

Get User Info

GET https://api.weellu.com/api/v1/admin-panel/user/info/:id

Returns detailed information about a specific user.

Path Parameters

Parameter Type Required Description
id string Yes The user ID (MongoDB ObjectId)

Example Request

curl "https://api.weellu.com/api/v1/admin-panel/user/info/659f1a2b3c4d5e6f7a8b9c0d" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/user/info/659f1a2b3c4d5e6f7a8b9c0d",
  {
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/admin-panel/user/info/659f1a2b3c4d5e6f7a8b9c0d',
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "659f1a2b3c4d5e6f7a8b9c0d",
    "fullName": "John Doe",
    "email": "john@example.com",
    "registerStatus": "approved",
    "bio": "Flutter developer",
    "userImage": "https://weellu-bucket.s3.amazonaws.com/users/john.jpg",
    "lastSeenAt": "2026-03-18T10:00:00.000Z",
    "createdAt": "2026-01-15T08:00:00.000Z",
    "devices": [
      {
        "platform": "android",
        "lastActive": "2026-03-18T10:00:00.000Z"
      }
    ]
  }
}

Update User Info

PATCH https://api.weellu.com/api/v1/admin-panel/user/info/:id

Updates information for a specific user. Accepts any user fields as body parameters.

Path Parameters

Parameter Type Required Description
id string Yes The user ID (MongoDB ObjectId)

Body Parameters

Parameter Type Required Description
(any user field) any No Any valid user field to update (e.g., fullName, registerStatus, bio)

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/admin-panel/user/info/659f1a2b3c4d5e6f7a8b9c0d" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "registerStatus": "blocked"
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/user/info/659f1a2b3c4d5e6f7a8b9c0d",
  {
    method: "PATCH",
    headers: {
      Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      registerStatus: "blocked",
    }),
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/api/v1/admin-panel/user/info/659f1a2b3c4d5e6f7a8b9c0d',
  body: {
    'registerStatus': 'blocked',
  },
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "659f1a2b3c4d5e6f7a8b9c0d",
    "fullName": "John Doe",
    "registerStatus": "blocked"
  }
}

Set New Version

PATCH https://api.weellu.com/api/v1/admin-panel/versions

Creates or updates a platform version entry. Used to manage app version requirements and update notifications.

Body Parameters

Parameter Type Required Description
semVer string Yes Semantic version string (e.g., "2.5.0")
buildNumber number Yes Build number (integer)
notify boolean Yes Whether to send a push notification about this version
notes string No Release notes
title string No Version title
description string No Version description
platform string Yes Target platform. One of: android, ios, web, desktop
critical boolean Yes Whether this is a critical/mandatory update
isForce boolean No Whether to force users to update immediately

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/admin-panel/versions" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "semVer": "2.5.0",
    "buildNumber": 125,
    "notify": true,
    "title": "New Features Release",
    "description": "Added marketplace and improved performance",
    "notes": "Bug fixes and performance improvements",
    "platform": "android",
    "critical": false,
    "isForce": false
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/versions",
  {
    method: "PATCH",
    headers: {
      Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      semVer: "2.5.0",
      buildNumber: 125,
      notify: true,
      title: "New Features Release",
      description: "Added marketplace and improved performance",
      notes: "Bug fixes and performance improvements",
      platform: "android",
      critical: false,
      isForce: false,
    }),
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/api/v1/admin-panel/versions',
  body: {
    'semVer': '2.5.0',
    'buildNumber': 125,
    'notify': true,
    'title': 'New Features Release',
    'platform': 'android',
    'critical': false,
    'isForce': false,
  },
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "66238c9d0e1f2a3b4c5d6e7f",
    "semVer": "2.5.0",
    "buildNumber": 125,
    "platform": "android",
    "critical": false,
    "isForce": false,
    "title": "New Features Release",
    "description": "Added marketplace and improved performance",
    "notes": "Bug fixes and performance improvements",
    "createdAt": "2026-03-18T12:00:00.000Z"
  }
}

Get Version Dashboard

GET https://api.weellu.com/api/v1/admin-panel/versions/:platform

Returns version history for a specific platform.

Path Parameters

Parameter Type Required Description
platform string Yes The platform to get versions for. One of: android, ios, web, desktop

Example Request

curl "https://api.weellu.com/api/v1/admin-panel/versions/android" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/versions/android",
  {
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/admin-panel/versions/android',
);

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "66238c9d0e1f2a3b4c5d6e7f",
      "semVer": "2.5.0",
      "buildNumber": 125,
      "platform": "android",
      "critical": false,
      "isForce": false,
      "title": "New Features Release",
      "createdAt": "2026-03-18T12:00:00.000Z"
    },
    {
      "_id": "66228c9d0e1f2a3b4c5d6e7e",
      "semVer": "2.4.2",
      "buildNumber": 122,
      "platform": "android",
      "critical": true,
      "isForce": true,
      "title": "Security Patch",
      "createdAt": "2026-03-10T09:00:00.000Z"
    }
  ]
}

Delete Version

DELETE https://api.weellu.com/api/v1/admin-panel/versions/:id

Deletes a version entry.

Path Parameters

Parameter Type Required Description
id string Yes The version entry ID (MongoDB ObjectId)

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/admin-panel/versions/66238c9d0e1f2a3b4c5d6e7f" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/versions/66238c9d0e1f2a3b4c5d6e7f",
  {
    method: "DELETE",
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/api/v1/admin-panel/versions/66238c9d0e1f2a3b4c5d6e7f',
);

Example Response

{
  "code": 200,
  "data": {
    "message": "Version deleted successfully"
  }
}

Create Admin Notification

POST https://api.weellu.com/api/v1/admin-panel/notifications

Sends a push notification to all users or a targeted group. Accepts an optional image via multipart form data.

Body Parameters (multipart/form-data)

Parameter Type Required Description
title string Yes Notification title
content string Yes Notification body text
file file No Optional image to include with the notification

Example Request

curl -X POST "https://api.weellu.com/api/v1/admin-panel/notifications" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN" \
  -F "title=System Maintenance" \
  -F "content=We will perform scheduled maintenance on March 20th from 2AM-4AM UTC." \
  -F "file=@notification_banner.png"
const formData = new FormData();
formData.append("title", "System Maintenance");
formData.append("content", "We will perform scheduled maintenance on March 20th from 2AM-4AM UTC.");
formData.append("file", imageFile);

const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/notifications",
  {
    method: "POST",
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
    body: formData,
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/admin-panel/notifications'),
);
request.headers['Authorization'] = 'Bearer SUPER_ADMIN_JWT_TOKEN';
request.fields['title'] = 'System Maintenance';
request.fields['content'] = 'We will perform scheduled maintenance...';
request.files.add(await http.MultipartFile.fromPath('file', 'banner.png'));
final response = await request.send();

Example Response

{
  "code": 200,
  "data": {
    "_id": "66249d0e1f2a3b4c5d6e7f8a",
    "title": "System Maintenance",
    "content": "We will perform scheduled maintenance on March 20th from 2AM-4AM UTC.",
    "imageUrl": "https://weellu-bucket.s3.amazonaws.com/notifications/banner.png",
    "createdAt": "2026-03-18T12:30:00.000Z"
  }
}

Get Admin Notifications

GET https://api.weellu.com/api/v1/admin-panel/notifications

Returns a list of all admin-sent notifications.

Parameters

No parameters required.

Example Request

curl "https://api.weellu.com/api/v1/admin-panel/notifications" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/notifications",
  {
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/admin-panel/notifications',
);

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "66249d0e1f2a3b4c5d6e7f8a",
      "title": "System Maintenance",
      "content": "We will perform scheduled maintenance on March 20th from 2AM-4AM UTC.",
      "imageUrl": "https://weellu-bucket.s3.amazonaws.com/notifications/banner.png",
      "createdAt": "2026-03-18T12:30:00.000Z"
    }
  ]
}

Create Product Category

POST https://api.weellu.com/api/v1/admin-panel/category/create

Creates a new product category for the marketplace.

Body Parameters

Parameter Type Required Description
name string Yes Category display name
icon string No Icon identifier or URL
iconColor string No Hex color code for the icon
parentId string No Parent category ID for creating subcategories (MongoDB ObjectId)

Example Request

curl -X POST "https://api.weellu.com/api/v1/admin-panel/category/create" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Electronics",
    "icon": "devices",
    "iconColor": "#2196F3"
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/category/create",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      name: "Electronics",
      icon: "devices",
      iconColor: "#2196F3",
    }),
  }
);
const data = await response.json();
final response = await chopper.post(
  '/api/v1/admin-panel/category/create',
  body: {
    'name': 'Electronics',
    'icon': 'devices',
    'iconColor': '#2196F3',
  },
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "6625ae1f2a3b4c5d6e7f8a9b",
    "name": "Electronics",
    "icon": "devices",
    "iconColor": "#2196F3",
    "parentId": null,
    "createdAt": "2026-03-18T13:00:00.000Z"
  }
}

Update Product Category

PATCH https://api.weellu.com/api/v1/admin-panel/category/:id/update

Updates an existing product category.

Path Parameters

Parameter Type Required Description
id string Yes The category ID (MongoDB ObjectId)

Body Parameters

Parameter Type Required Description
name string No Updated category name
icon string No Updated icon identifier
iconColor string No Updated hex color code

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/admin-panel/category/6625ae1f2a3b4c5d6e7f8a9b/update" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Electronics & Gadgets",
    "iconColor": "#1565C0"
  }'
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/category/6625ae1f2a3b4c5d6e7f8a9b/update",
  {
    method: "PATCH",
    headers: {
      Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      name: "Electronics & Gadgets",
      iconColor: "#1565C0",
    }),
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/api/v1/admin-panel/category/6625ae1f2a3b4c5d6e7f8a9b/update',
  body: {
    'name': 'Electronics & Gadgets',
    'iconColor': '#1565C0',
  },
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "6625ae1f2a3b4c5d6e7f8a9b",
    "name": "Electronics & Gadgets",
    "icon": "devices",
    "iconColor": "#1565C0"
  }
}

Delete Product Category

DELETE https://api.weellu.com/api/v1/admin-panel/category/:id/delete

Deletes a product category. Categories with child subcategories should be handled with care.

Path Parameters

Parameter Type Required Description
id string Yes The category ID (MongoDB ObjectId)

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/admin-panel/category/6625ae1f2a3b4c5d6e7f8a9b/delete" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/category/6625ae1f2a3b4c5d6e7f8a9b/delete",
  {
    method: "DELETE",
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/api/v1/admin-panel/category/6625ae1f2a3b4c5d6e7f8a9b/delete',
);

Example Response

{
  "code": 200,
  "data": {
    "message": "Category deleted successfully"
  }
}

Get All Categories

GET https://api.weellu.com/api/v1/admin-panel/category/all

Returns all product categories with optional filtering.

Query Parameters

Parameter Type Required Description
page number No Page number
limit number No Categories per page

Example Request

curl "https://api.weellu.com/api/v1/admin-panel/category/all" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/category/all",
  {
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/admin-panel/category/all',
);

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "6625ae1f2a3b4c5d6e7f8a9b",
      "name": "Electronics",
      "icon": "devices",
      "iconColor": "#2196F3",
      "parentId": null
    },
    {
      "_id": "6625bf2a3b4c5d6e7f8a9b0c",
      "name": "Smartphones",
      "icon": "smartphone",
      "iconColor": "#4CAF50",
      "parentId": "6625ae1f2a3b4c5d6e7f8a9b"
    }
  ]
}

Get User Reports

GET https://api.weellu.com/api/v1/admin-panel/users/reports

Returns user-submitted reports with optional filtering.

Query Parameters

Parameter Type Required Description
page number No Page number
limit number No Reports per page
type string No Filter by report type

Example Request

curl "https://api.weellu.com/api/v1/admin-panel/users/reports?page=1&limit=20" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/users/reports?page=1&limit=20",
  {
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/admin-panel/users/reports',
  parameters: {'page': 1, 'limit': 20},
);

Example Response

{
  "code": 200,
  "data": {
    "docs": [
      {
        "_id": "6626c03b4c5d6e7f8a9b0c1d",
        "content": "App crashes on video call",
        "stack": "Error: MediaStream initialization failed",
        "type": "crash",
        "platform": "android",
        "uId": "659f1a2b3c4d5e6f7a8b9c0d",
        "createdAt": "2026-03-18T10:30:00.000Z"
      }
    ],
    "totalDocs": 42,
    "limit": 20,
    "page": 1,
    "totalPages": 3
  }
}

Delete Report

DELETE https://api.weellu.com/api/v1/admin-panel/users/reports/:id

Deletes a specific user report.

Path Parameters

Parameter Type Required Description
id string Yes The report ID (MongoDB ObjectId)

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/admin-panel/users/reports/6626c03b4c5d6e7f8a9b0c1d" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/users/reports/6626c03b4c5d6e7f8a9b0c1d",
  {
    method: "DELETE",
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/api/v1/admin-panel/users/reports/6626c03b4c5d6e7f8a9b0c1d',
);

Example Response

{
  "code": 200,
  "data": {
    "message": "Report deleted successfully"
  }
}

Get API Token Requests

GET https://api.weellu.com/api/v1/admin-panel/users/api

Returns a list of user API token requests with filtering options.

Query Parameters

Parameter Type Required Description
page number No Page number
limit number No Requests per page

Example Request

curl "https://api.weellu.com/api/v1/admin-panel/users/api?page=1&limit=20" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/users/api?page=1&limit=20",
  {
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/admin-panel/users/api',
  parameters: {'page': 1, 'limit': 20},
);

Example Response

{
  "code": 200,
  "data": {
    "docs": [
      {
        "_id": "6627d14c5d6e7f8a9b0c1d2e",
        "userId": "659f1a2b3c4d5e6f7a8b9c0d",
        "status": "pending",
        "createdAt": "2026-03-18T10:00:00.000Z"
      }
    ],
    "totalDocs": 5,
    "limit": 20,
    "page": 1,
    "totalPages": 1
  }
}

Update API Token Request

PATCH https://api.weellu.com/api/v1/admin-panel/users/api/:id

Updates the status of a user's API token request (approve, reject, etc.).

Path Parameters

Parameter Type Required Description
id string Yes The API token request ID (MongoDB ObjectId)

Query Parameters

Parameter Type Required Description
status string No New status for the request. One of the ApiTokenType enum values

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/admin-panel/users/api/6627d14c5d6e7f8a9b0c1d2e?status=approved" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/users/api/6627d14c5d6e7f8a9b0c1d2e?status=approved",
  {
    method: "PATCH",
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.patch(
  '/api/v1/admin-panel/users/api/6627d14c5d6e7f8a9b0c1d2e',
  parameters: {'status': 'approved'},
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "6627d14c5d6e7f8a9b0c1d2e",
    "userId": "659f1a2b3c4d5e6f7a8b9c0d",
    "status": "approved"
  }
}

Get Countries Info

GET https://api.weellu.com/api/v1/admin-panel/countries

Returns country distribution data for all registered users.

Parameters

No parameters required.

Example Request

curl "https://api.weellu.com/api/v1/admin-panel/countries" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/countries",
  {
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/admin-panel/countries',
);

Example Response

{
  "code": 200,
  "data": [
    {
      "country": "BR",
      "count": 5420
    },
    {
      "country": "US",
      "count": 3100
    },
    {
      "country": "PT",
      "count": 1850
    }
  ]
}

Get Banners

GET https://api.weellu.com/api/v1/admin-panel/banners

Returns all marketplace banners.

Parameters

No parameters required.

Example Request

curl "https://api.weellu.com/api/v1/admin-panel/banners" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/banners",
  {
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/admin-panel/banners',
);

Example Response

{
  "code": 200,
  "data": [
    {
      "_id": "6628e25d6e7f8a9b0c1d2e3f",
      "imageUrl": "https://weellu-bucket.s3.amazonaws.com/banners/spring_sale.jpg",
      "redirectUrl": "https://weellu.com/market/sale",
      "order": 0,
      "createdAt": "2026-03-15T09:00:00.000Z"
    },
    {
      "_id": "6628f36e7f8a9b0c1d2e3f4a",
      "imageUrl": "https://weellu-bucket.s3.amazonaws.com/banners/new_arrivals.jpg",
      "redirectUrl": "https://weellu.com/market/new",
      "order": 1,
      "createdAt": "2026-03-14T09:00:00.000Z"
    }
  ]
}

Get Banner by ID

GET https://api.weellu.com/api/v1/admin-panel/banners/:id

Returns a single banner by its ID.

Path Parameters

Parameter Type Required Description
id string Yes The banner ID (MongoDB ObjectId)

Example Request

curl "https://api.weellu.com/api/v1/admin-panel/banners/6628e25d6e7f8a9b0c1d2e3f" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/banners/6628e25d6e7f8a9b0c1d2e3f",
  {
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.get(
  '/api/v1/admin-panel/banners/6628e25d6e7f8a9b0c1d2e3f',
);

Example Response

{
  "code": 200,
  "data": {
    "_id": "6628e25d6e7f8a9b0c1d2e3f",
    "imageUrl": "https://weellu-bucket.s3.amazonaws.com/banners/spring_sale.jpg",
    "redirectUrl": "https://weellu.com/market/sale",
    "order": 0,
    "createdAt": "2026-03-15T09:00:00.000Z"
  }
}

Create Banner

POST https://api.weellu.com/api/v1/admin-panel/banners

Creates a new marketplace banner. Accepts an image via multipart form data.

Body Parameters (multipart/form-data)

Parameter Type Required Description
redirectUrl string Yes URL to redirect to when the banner is tapped. Must be a valid URL
order number No Display order (0-based). Lower numbers appear first. Default: 0
file file No Banner image file

Example Request

curl -X POST "https://api.weellu.com/api/v1/admin-panel/banners" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN" \
  -F "redirectUrl=https://weellu.com/market/flash-sale" \
  -F "order=0" \
  -F "file=@banner_image.jpg"
const formData = new FormData();
formData.append("redirectUrl", "https://weellu.com/market/flash-sale");
formData.append("order", "0");
formData.append("file", bannerImageFile);

const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/banners",
  {
    method: "POST",
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
    body: formData,
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'POST',
  Uri.parse('https://api.weellu.com/api/v1/admin-panel/banners'),
);
request.headers['Authorization'] = 'Bearer SUPER_ADMIN_JWT_TOKEN';
request.fields['redirectUrl'] = 'https://weellu.com/market/flash-sale';
request.fields['order'] = '0';
request.files.add(await http.MultipartFile.fromPath('file', 'banner.jpg'));
final response = await request.send();

Example Response

{
  "code": 200,
  "data": {
    "_id": "6629a47f8a9b0c1d2e3f4a5b",
    "imageUrl": "https://weellu-bucket.s3.amazonaws.com/banners/flash_sale.jpg",
    "redirectUrl": "https://weellu.com/market/flash-sale",
    "order": 0,
    "createdAt": "2026-03-18T14:00:00.000Z"
  }
}

Update Banner

PATCH https://api.weellu.com/api/v1/admin-panel/banners/:id

Updates an existing banner. Supports updating the redirect URL, display order, and image.

Path Parameters

Parameter Type Required Description
id string Yes The banner ID (MongoDB ObjectId)

Body Parameters (multipart/form-data)

Parameter Type Required Description
redirectUrl string No Updated redirect URL. Must be a valid URL
order number No Updated display order
file file No New banner image file

Example Request

curl -X PATCH "https://api.weellu.com/api/v1/admin-panel/banners/6628e25d6e7f8a9b0c1d2e3f" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN" \
  -F "redirectUrl=https://weellu.com/market/updated-sale" \
  -F "order=2"
const formData = new FormData();
formData.append("redirectUrl", "https://weellu.com/market/updated-sale");
formData.append("order", "2");

const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/banners/6628e25d6e7f8a9b0c1d2e3f",
  {
    method: "PATCH",
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
    body: formData,
  }
);
const data = await response.json();
final request = http.MultipartRequest(
  'PATCH',
  Uri.parse('https://api.weellu.com/api/v1/admin-panel/banners/6628e25d6e7f8a9b0c1d2e3f'),
);
request.headers['Authorization'] = 'Bearer SUPER_ADMIN_JWT_TOKEN';
request.fields['redirectUrl'] = 'https://weellu.com/market/updated-sale';
request.fields['order'] = '2';
final response = await request.send();

Example Response

{
  "code": 200,
  "data": {
    "_id": "6628e25d6e7f8a9b0c1d2e3f",
    "imageUrl": "https://weellu-bucket.s3.amazonaws.com/banners/spring_sale.jpg",
    "redirectUrl": "https://weellu.com/market/updated-sale",
    "order": 2
  }
}

Delete Banner

DELETE https://api.weellu.com/api/v1/admin-panel/banners/:id

Deletes a marketplace banner.

Path Parameters

Parameter Type Required Description
id string Yes The banner ID (MongoDB ObjectId)

Example Request

curl -X DELETE "https://api.weellu.com/api/v1/admin-panel/banners/6628e25d6e7f8a9b0c1d2e3f" \
  -H "Authorization: Bearer SUPER_ADMIN_JWT_TOKEN"
const response = await fetch(
  "https://api.weellu.com/api/v1/admin-panel/banners/6628e25d6e7f8a9b0c1d2e3f",
  {
    method: "DELETE",
    headers: { Authorization: "Bearer SUPER_ADMIN_JWT_TOKEN" },
  }
);
const data = await response.json();
final response = await chopper.delete(
  '/api/v1/admin-panel/banners/6628e25d6e7f8a9b0c1d2e3f',
);

Example Response

{
  "code": 200,
  "data": {
    "message": "Banner deleted successfully"
  }
}

Errors

The Weellu API uses a consistent error response format across all endpoints. When an error occurs, the response body follows this structure:

Error Response Format

{
  "statusCode": 400,
  "timestamp": "2026-03-18T10:30:00.000Z",
  "path": "/api/v1/endpoint",
  "data": "t.errorKey"
}

Error Response Fields

Field Type Description
statusCode number HTTP status code
timestamp string ISO 8601 timestamp of when the error occurred
path string The request URL path that caused the error
data string Error message prefixed with t. indicating an i18n translation key. Clients should strip the t. prefix and use the remaining key for localized error display

Validation Errors

When request body validation fails (via class-validator), the API returns the first validation error message as the data field.

Validation Error Example

{
  "statusCode": 400,
  "timestamp": "2026-03-18T10:30:00.000Z",
  "path": "/api/v1/auth/register",
  "data": "t.email must be an email"
}

Error Codes

The Weellu API uses the following standard HTTP error codes:

Error Code Meaning
400 Bad Request -- The request body is malformed, a required field is missing, or validation failed. Check the data field for the specific validation error.
401 Unauthorized -- No valid Bearer token was provided, or the token has expired. Re-authenticate and retry with a fresh JWT.
403 Forbidden -- The authenticated user does not have permission to perform this action. Common when accessing SuperAdmin endpoints without the required role.
404 Not Found -- The requested resource does not exist. Verify the ID or path is correct.
405 Method Not Allowed -- The HTTP method is not supported for this endpoint. Check the documentation for the correct method (GET, POST, PUT, PATCH, DELETE).
406 Not Acceptable -- The request format is not supported. The API only returns JSON responses.
409 Conflict -- The request conflicts with the current state of the resource. Common when trying to create a duplicate entry or when an operation cannot be performed due to the current state.
410 Gone -- The requested resource has been permanently deleted and is no longer available.
422 Unprocessable Entity -- The request was well-formed but contains semantic errors. For example, trying to ban a user who is already banned, or completing a multipart upload with missing parts.
429 Too Many Requests -- Rate limit exceeded. The API uses throttling to protect against abuse. Wait before retrying.
500 Internal Server Error -- An unexpected error occurred on the server. If this persists, report it via the report system endpoint.
503 Service Unavailable -- The server is temporarily offline for maintenance or is overloaded. Retry after a short delay.

Common Error Scenarios

401 Unauthorized - Invalid or expired token

{
  "statusCode": 401,
  "timestamp": "2026-03-18T10:30:00.000Z",
  "path": "/api/v1/activity-notifications/feed",
  "data": "t.Unauthorized"
}

403 Forbidden - Insufficient permissions

{
  "statusCode": 403,
  "timestamp": "2026-03-18T10:30:00.000Z",
  "path": "/api/v1/admin-panel/dashboard",
  "data": "t.Forbidden"
}

404 Not Found - Resource does not exist

{
  "statusCode": 404,
  "timestamp": "2026-03-18T10:30:00.000Z",
  "path": "/api/v1/room-filters/660e5f6a7b8c9d0e1f2a3b4c",
  "data": "t.notFound"
}

409 Conflict - Duplicate or state conflict

{
  "statusCode": 409,
  "timestamp": "2026-03-18T10:30:00.000Z",
  "path": "/api/v1/user-ban/659f2b3c4d5e6f7a8b9c0d1e/ban",
  "data": "t.userAlreadyBanned"
}

422 Unprocessable Entity - Semantic error

{
  "statusCode": 422,
  "timestamp": "2026-03-18T10:30:00.000Z",
  "path": "/api/v1/multipart-upload/complete",
  "data": "t.missingParts"
}

429 Too Many Requests - Rate limited

{
  "statusCode": 429,
  "timestamp": "2026-03-18T10:30:00.000Z",
  "path": "/api/v1/auth/login",
  "data": "t.ThrottlerException: Too Many Requests"
}

500 Internal Server Error

{
  "statusCode": 500,
  "timestamp": "2026-03-18T10:30:00.000Z",
  "path": "/api/v1/market/home",
  "data": "t.Error: Internal server error"
}

Error Handling Best Practices

  1. Always check the statusCode field to determine the category of error.
  2. Parse the data field by stripping the t. prefix to get the i18n translation key.
  3. Implement retry logic for 429 and 503 errors with exponential backoff.
  4. Re-authenticate when receiving 401 errors by refreshing the JWT token.
  5. Log 500 errors and report them via POST /api/v1/report-system for investigation.