الأعضاء — roles, permissions, titles, supervisors, profiles and removal.
Who may act on whom:
roleandpermissionsneedusers:manage, which only admins hold (it cannot be delegated). No one assigns a role above their own, and nothing may leave a community without an admin (409LAST_ADMIN).- The community's founder is protected: only the founder (or a platform
super-admin) can change the founder's role or permissions
(403
OWNER_PROTECTED). - title, supervisor and profile-as-admin need
users:manageorusers:moderate(a moderator default), and the target may not rank ABOVE the caller (403MEMBER_OUTRANKS_ACTOR) — a moderator cannot edit an admin; peers may edit each other. - ban and remove need the caller to rank strictly ABOVE the target.
memberIdis theCommunityMember.id, always resolved inside the URL's community — an id from another community is a 404.
14 endpoints.
| Method | Path | Summary |
|---|---|---|
POST | /api/communities/{communityId}/groups/members/batch | Members of several groups in one call (names and avatars only) |
POST | /api/communities/{communityId}/join-request | Request to join a public community |
GET | /api/communities/{communityId}/member-requests | Get pending member requests (admin/moderator only) |
DELETE | /api/communities/{communityId}/members/{memberId} | Remove member from community (soft delete) |
POST | /api/communities/{communityId}/members/{memberId}/ban | Ban or unban a member |
PUT | /api/communities/{communityId}/members/{memberId}/permissions | Update member permissions (admin only) |
PUT | /api/communities/{communityId}/members/{memberId}/profile | Edit a member's profile as an admin or moderator |
PUT | /api/communities/{communityId}/members/{memberId}/role | Update member role (admin only) |
PUT | /api/communities/{communityId}/members/{memberId}/supervisor | Assign (or clear) a member's supervisor — المشرف المسؤول |
PUT | /api/communities/{communityId}/members/{memberId}/title | Set a member's role title and/or honorific |
DELETE | /api/communities/{communityId}/members/bulk | Bulk remove members from community |
PUT | /api/communities/{communityId}/members/me/profile | Edit my profile in this community |
POST | /api/communities/{communityId}/members/supervisors/resolve-by-email | Link supervisors by email in bulk (the Excel import's second pass) |
GET | /api/communities/{communityId}/users/{userId}/permissions | Get user permissions in community |
POST /api/communities/{communityId}/groups/members/batchAuth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
Request body (required) — application/json
| Field | Type | Required | Description |
|---|---|---|---|
groupIds | string[] | yes | — |
limit | integer | no | — |
orderBy | string | no | — |
Responses
| Status | Description | Body |
|---|---|---|
200 | Members per group; groups the caller cannot see are dropped | — |
POST /api/communities/{communityId}/join-requestAuth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
Responses
| Status | Description | Body |
|---|---|---|
200 | Join request submitted | — |
GET /api/communities/{communityId}/member-requestsAuth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
page | query | no | integer | — |
limit | query | no | integer | — |
Responses
| Status | Description | Body |
|---|---|---|
200 | Paginated list of member requests | — |
403 | Permission denied | — |
DELETE /api/communities/{communityId}/members/{memberId}Soft-deletes a community member by setting their status to LEFT. Supports both self-removal (user leaving) and admin/moderator-initiated removal.
Behavior:
- Cascade cleanup: removes group memberships, event attendance, and likes
- Last admin protection: cannot remove the only COMMUNITY_ADMIN
- Role hierarchy: moderators cannot remove admins or other moderators
- Audit trail: stores removal metadata (who, when, reason) in member permissions
- Real-time: emits
member:removedsocket event to invalidate active sessions - Email: sends removal notification email (admin-initiated removals only)
Authorization:
- Self-removal: any authenticated member can remove themselves
- Admin removal: requires
users:manageorusers:moderatepermission
Auth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | UUID of the community |
memberId | path | yes | string (uuid) | UUID of the community member to remove |
Request body — application/json
| Field | Type | Required | Description |
|---|---|---|---|
reason | string | no | Optional reason for removal (admin-initiated only, sanitized) |
Responses
| Status | Description | Body |
|---|---|---|
200 | Member removed successfully | object |
400 | Bad request - invalid UUID, member already left, member is banned, or last admin | object |
401 | Authentication required | — |
403 | Permission denied - insufficient role or cannot remove higher-ranked member | object |
404 | Member not found | — |
500 | Internal server error | — |
POST /api/communities/{communityId}/members/{memberId}/banAuth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
memberId | path | yes | string (uuid) | — |
Responses
| Status | Description | Body |
|---|---|---|
200 | Ban status toggled successfully | — |
403 | Permission denied | — |
PUT /api/communities/{communityId}/members/{memberId}/permissionsSets the member's role AND legacy can* flags in one write. role is
required (it used to default to MEMBER, silently demoting the target).
Refused when it would leave the community with no admin.
Auth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
memberId | path | yes | string (uuid) | — |
Request body (required) — application/json
| Field | Type | Required | Description |
|---|---|---|---|
role | enum: MEMBER, MODERATOR, COMMUNITY_ADMIN | yes | — |
Responses
| Status | Description | Body |
|---|---|---|
200 | Permissions updated successfully | — |
400 | ROLE_REQUIRED, or INVALID_ROLE | — |
403 | Needs users:manage (admins only), or a role above your own; OWNER_PROTECTED when the target is the community's founder and the caller is not the founder | — |
404 | MEMBER_NOT_FOUND — not an APPROVED member of this community | — |
409 | LAST_ADMIN — this would leave the community without an admin | — |
PUT /api/communities/{communityId}/members/{memberId}/profileSame fields as me/profile. Refused for a target ranked above the caller.
Auth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
memberId | path | yes | string (uuid) | CommunityMember.id |
Responses
| Status | Description | Body |
|---|---|---|
200 | profile is the updated MemberProfile | — |
403 | Missing permission, or MEMBER_OUTRANKS_ACTOR | — |
404 | Member not found in this community | — |
PUT /api/communities/{communityId}/members/{memberId}/roleAuth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
memberId | path | yes | string (uuid) | — |
Request body (required) — application/json
| Field | Type | Required | Description |
|---|---|---|---|
role | enum: MEMBER, MODERATOR, COMMUNITY_ADMIN | yes | — |
moderatorTitle | string | no | Optional, kept only when role is MODERATOR |
Responses
| Status | Description | Body |
|---|---|---|
200 | Role updated successfully | — |
400 | INVALID_ROLE, a title that is too long, or demoting the only Community Admin | — |
403 | Needs users:manage, or a role above your own; OWNER_PROTECTED when the target is the community's founder and the caller is not the founder | — |
404 | Member not found | — |
PUT /api/communities/{communityId}/members/{memberId}/supervisorAuth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
memberId | path | yes | string (uuid) | CommunityMember.id |
Request body (required) — application/json
| Field | Type | Required | Description |
|---|---|---|---|
supervisorMemberId | string | no | CommunityMember.id of an APPROVED member; null clears |
Responses
| Status | Description | Body |
|---|---|---|
200 | Updated | — |
403 | Missing permission, or MEMBER_OUTRANKS_ACTOR | — |
404 | Member or supervisor not found in this community | — |
PUT /api/communities/{communityId}/members/{memberId}/titleAuth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
memberId | path | yes | string (uuid) | CommunityMember.id |
Request body (required) — application/json
| Field | Type | Required | Description |
|---|---|---|---|
moderatorTitle | string | no | Role-badge title; null clears it |
honorificTitle | string | no | Honorific; null clears it |
Responses
| Status | Description | Body |
|---|---|---|
200 | Updated | — |
400 | Neither field sent | — |
403 | Missing permission, or MEMBER_OUTRANKS_ACTOR | — |
404 | MEMBER_NOT_FOUND | — |
DELETE /api/communities/{communityId}/members/bulkRemoves multiple community members in a single request (soft delete, status set to LEFT). Processes removals sequentially to prevent race conditions on memberCount. Returns partial success results — some members may fail while others succeed.
Constraints:
- Maximum 50 members per request
- Rate limited: 5 requests per 15 minutes per IP
- Cannot include your own memberId (self-removal blocked)
- Last admin protection: cannot remove the only COMMUNITY_ADMIN
- Role hierarchy: moderators cannot remove admins or other moderators
- Reason is required (min 3 chars, max 500 chars, sanitized)
Side effects per member:
- Cascade cleanup: removes group memberships, event attendance, likes
- Real-time: emits
member:removedsocket event - Email: sends removal notification
Auth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | UUID of the community |
Request body (required) — application/json
| Field | Type | Required | Description |
|---|---|---|---|
memberIds | string (uuid)[] | yes | Array of community member UUIDs to remove |
reason | string | yes | Reason for removal (required, sanitized, min 3 chars) |
Responses
| Status | Description | Body |
|---|---|---|
200 | Bulk removal completed (may include partial failures) | object |
400 | Bad request - invalid input, self-removal attempt, or reason too short | object |
401 | Authentication required | — |
403 | Permission denied - requires users:manage or users:moderate | — |
429 | Rate limit exceeded (5 requests per 15 minutes) | object |
500 | Internal server error | — |
PUT /api/communities/{communityId}/members/me/profileName, phone, bio, city, job and socials are per-community (MemberProfile). multipart/form-data; files avatar, coverImage. Avatars are outside the community storage quota by design.
Auth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
Responses
| Status | Description | Body |
|---|---|---|
200 | profile is the updated MemberProfile | — |
POST /api/communities/{communityId}/members/supervisors/resolve-by-emailAuth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
Request body (required) — application/json
| Field | Type | Required | Description |
|---|---|---|---|
pairs | object[] | no | — |
Responses
| Status | Description | Body |
|---|---|---|
200 | Per-pair results (an unknown email reports MEMBER_NOT_FOUND) | — |
GET /api/communities/{communityId}/users/{userId}/permissionsAuth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
userId | path | yes | string (uuid) | — |
Responses
| Status | Description | Body |
|---|---|---|
200 | User permissions | — |
401 | Authentication required | — |