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 |
|---|---|---|---|
| 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 |
|---|---|---|---|
| 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 |
|---|---|---|---|
| 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 |
|---|---|---|---|
| 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 |
|---|---|---|---|
| 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
targetUserIds: 1 to 50 user IDsminutes: 1 to 525600 (1 minute to 365 days)customMessage: up to 500 characters
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
- Always check the
statusCodefield to determine the category of error. - Parse the
datafield by stripping thet.prefix to get the i18n translation key. - Implement retry logic for 429 and 503 errors with exponential backoff.
- Re-authenticate when receiving 401 errors by refreshing the JWT token.
- Log 500 errors and report them via
POST /api/v1/report-systemfor investigation.