BrightChat API Reference
Complete HTTP API reference for BrightChat, BrightChain’s real-time communication system. BrightChat provides three communication modes — direct messages, group chats, and channels — with end-to-end encryption (ECIES + AES-256-GCM) and role-based permissions.
API Sections
- Direct Messages —
/api/conversations - Groups —
/api/groups - Channels —
/api/channels
Direct Messages (/api/conversations)
Person-to-person encrypted messaging with conversation promotion to groups.
Endpoints Overview
| Method | Path | Description |
|---|---|---|
| POST | / | Send a direct message |
| GET | / | List conversations (paginated) |
| GET | /:conversationId/messages | Get messages (cursor-based pagination) |
| DELETE | /:conversationId/messages/:messageId | Delete a message |
| POST | /:conversationId/promote | Promote conversation to a group |
POST /
Send a direct message. If no conversation exists between the two members, one is created automatically. Each message is encrypted with the recipient’s secp256k1 public key using ECIES.
Request:
{
"recipientId": "member-uuid-2",
"content": "Hey, are you free for a call?"
}
201 Response:
{
"status": "success",
"data": {
"id": "message-uuid",
"conversationId": "conv-uuid",
"senderId": "member-uuid-1",
"recipientId": "member-uuid-2",
"encryptedContent": "...",
"createdAt": "2026-03-13T10:00:00.000Z"
},
"message": "Message sent"
}
Privacy-preserving error handling: blocked and non-existent members produce indistinguishable error responses to prevent enumeration.
Errors:
400— Missing required fields (recipientId,content)404— Recipient not reachable (blocked or non-existent)
GET /
List conversations for the authenticated member, sorted by most recent activity.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
cursor | string | Opaque cursor for next page |
limit | number | Results per page |
200 Response:
{
"status": "success",
"data": {
"items": [
{
"id": "conv-uuid",
"participants": ["member-uuid-1", "member-uuid-2"],
"lastMessageAt": "2026-03-13T10:00:00.000Z",
"lastMessagePreview": "Hey, are you free..."
}
],
"cursor": "next-page-cursor",
"hasMore": true
},
"message": "Conversations listed"
}
Errors:
401— Not authenticated
GET /:conversationId/messages
Get messages in a conversation with cursor-based pagination. Messages are returned in chronological order.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
cursor | string | Opaque cursor for next page |
limit | number | Results per page |
200 Response:
{
"status": "success",
"data": {
"items": [
{
"id": "message-uuid",
"senderId": "member-uuid-1",
"encryptedContent": "...",
"createdAt": "2026-03-13T10:00:00.000Z"
}
],
"cursor": "next-page-cursor",
"hasMore": false
},
"message": "Messages retrieved"
}
Errors:
403— Not a participant in this conversation404— Conversation not found
DELETE /:conversationId/messages/:messageId
Delete a message. Only the message author can delete their own messages.
200 Response:
{
"status": "success",
"data": { "deleted": true },
"message": "Message deleted"
}
Errors:
403— Not the message author404— Conversation or message not found
POST /:conversationId/promote
Promote a direct message conversation to a group chat. The full message history is preserved. Additional members can be added during promotion.
Request:
{
"newMemberIds": ["member-uuid-3", "member-uuid-4"]
}
200 Response:
{
"status": "success",
"data": {
"groupId": "group-uuid",
"name": "Group Chat",
"members": ["member-uuid-1", "member-uuid-2", "member-uuid-3", "member-uuid-4"],
"promotedFromConversation": "conv-uuid"
},
"message": "Conversation promoted to group"
}
Errors:
400— Missing required field (newMemberIdsmust be a non-empty array)403— Not a participant404— Conversation not found500— Group promotion not configured
Groups (/api/groups)
Multi-member encrypted group conversations with role-based permissions. Groups use a shared AES-256-GCM symmetric key that is encrypted per-member using ECIES, with automatic key rotation on membership changes.
Endpoints Overview
| Method | Path | Description |
|---|---|---|
| POST | / | Create a group |
| GET | /:groupId | Get group metadata |
| POST | /:groupId/messages | Send a message |
| GET | /:groupId/messages | Get message history |
| POST | /:groupId/members | Add members |
| DELETE | /:groupId/members/:memberId | Remove a member |
| POST | /:groupId/leave | Leave the group |
| PUT | /:groupId/roles/:memberId | Assign a role |
| POST | /:groupId/messages/:messageId/reactions | Add a reaction |
| DELETE | /:groupId/messages/:messageId/reactions/:reactionId | Remove a reaction |
| PUT | /:groupId/messages/:messageId | Edit a message |
| POST | /:groupId/messages/:messageId/pin | Pin a message |
| DELETE | /:groupId/messages/:messageId/pin | Unpin a message |
POST /
Create a new group chat.
Request:
{
"name": "Project Alpha",
"memberIds": ["member-uuid-2", "member-uuid-3"]
}
The creator is automatically added as the group owner.
201 Response:
{
"status": "success",
"data": {
"id": "group-uuid",
"name": "Project Alpha",
"creatorId": "member-uuid-1",
"members": [
{ "memberId": "member-uuid-1", "role": "owner", "joinedAt": "2026-03-13T10:00:00.000Z" },
{ "memberId": "member-uuid-2", "role": "member", "joinedAt": "2026-03-13T10:00:00.000Z" },
{ "memberId": "member-uuid-3", "role": "member", "joinedAt": "2026-03-13T10:00:00.000Z" }
],
"createdAt": "2026-03-13T10:00:00.000Z"
},
"message": "Group created"
}
Errors:
400— Missing required fields (name,memberIds)
GET /:groupId
Get group metadata including member list and roles.
200 Response:
{
"status": "success",
"data": {
"id": "group-uuid",
"name": "Project Alpha",
"creatorId": "member-uuid-1",
"members": [
{ "memberId": "member-uuid-1", "role": "owner", "joinedAt": "2026-03-13T10:00:00.000Z" },
{ "memberId": "member-uuid-2", "role": "admin", "joinedAt": "2026-03-13T10:00:00.000Z" }
],
"createdAt": "2026-03-13T10:00:00.000Z",
"lastMessageAt": "2026-03-13T14:30:00.000Z"
},
"message": "Group retrieved"
}
Errors:
403— Not a group member404— Group not found
POST /:groupId/messages
Send a message to the group. The message is encrypted with the group’s shared symmetric key.
Request:
{
"content": "Meeting at 3pm today"
}
201 Response:
{
"status": "success",
"data": {
"id": "message-uuid",
"groupId": "group-uuid",
"senderId": "member-uuid-1",
"encryptedContent": "...",
"createdAt": "2026-03-13T14:30:00.000Z"
},
"message": "Message sent"
}
Errors:
400— Missing required field (content)403— Not a group member, or member is muted404— Group not found
GET /:groupId/messages
Get message history with cursor-based pagination.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
cursor | string | Opaque cursor for next page |
limit | number | Results per page |
200 Response:
{
"status": "success",
"data": {
"items": [
{
"id": "message-uuid",
"senderId": "member-uuid-1",
"encryptedContent": "...",
"createdAt": "2026-03-13T14:30:00.000Z",
"editedAt": null,
"pinned": false,
"reactions": []
}
],
"cursor": "next-page-cursor",
"hasMore": true
},
"message": "Messages retrieved"
}
Errors:
403— Not a group member404— Group not found
POST /:groupId/members
Add one or more members to the group. Triggers automatic key rotation — a new shared symmetric key is generated and encrypted for all members (including new ones).
Request:
{
"memberIds": ["member-uuid-4", "member-uuid-5"]
}
200 Response:
{
"status": "success",
"data": { "added": ["member-uuid-4", "member-uuid-5"] },
"message": "Members added"
}
Errors:
400— Missing required field (memberIds)403— Insufficient permissions (MANAGE_MEMBERSrequired)404— Group not found409— Member already in group
DELETE /:groupId/members/:memberId
Remove a member from the group. Triggers key rotation so the removed member cannot decrypt future messages.
200 Response:
{
"status": "success",
"data": { "removed": "member-uuid-4" },
"message": "Member removed"
}
Errors:
403— Insufficient permissions (MANAGE_MEMBERSrequired)404— Group not found
POST /:groupId/leave
Voluntarily leave a group. Triggers key rotation.
200 Response:
{
"status": "success",
"data": { "left": true },
"message": "Left group"
}
Errors:
403— Not a group member404— Group not found
PUT /:groupId/roles/:memberId
Assign a role to a group member. Requires the MANAGE_ROLES permission (owner or admin).
Request:
{
"role": "moderator"
}
Available roles: owner, admin, moderator, member
200 Response:
{
"status": "success",
"data": { "memberId": "member-uuid-2", "role": "moderator" },
"message": "Role assigned"
}
Errors:
400— Missing required field (role)403— Missing permission:manage_roles404— Group not found
POST /:groupId/messages/:messageId/reactions
Add an emoji reaction to a message.
Request:
{
"emoji": "👍"
}
201 Response:
{
"status": "success",
"data": { "reactionId": "reaction-uuid", "emoji": "👍" },
"message": "Reaction added"
}
Errors:
400— Missing required field (emoji)403— Not a group member404— Group or message not found
DELETE /:groupId/messages/:messageId/reactions/:reactionId
Remove a reaction. Only the member who added the reaction can remove it.
200 Response:
{
"status": "success",
"data": { "removed": true },
"message": "Reaction removed"
}
Errors:
403— Not the reaction author404— Group, message, or reaction not found
PUT /:groupId/messages/:messageId
Edit a message. Only the original author can edit. Edit history is preserved.
Request:
{
"content": "Meeting at 4pm today (updated)"
}
200 Response:
{
"status": "success",
"data": {
"id": "message-uuid",
"senderId": "member-uuid-1",
"encryptedContent": "...",
"createdAt": "2026-03-13T14:30:00.000Z",
"editedAt": "2026-03-13T14:35:00.000Z",
"editHistory": [
{ "content": "...", "editedAt": "2026-03-13T14:30:00.000Z" }
]
},
"message": "Message edited"
}
Errors:
400— Missing required field (content)403— Not the message author404— Group or message not found
POST /:groupId/messages/:messageId/pin
Pin a message to the group. Requires PIN_MESSAGES permission.
200 Response:
{
"status": "success",
"data": { "pinned": true },
"message": "Message pinned"
}
Errors:
403— Insufficient permissions404— Group or message not found
DELETE /:groupId/messages/:messageId/pin
Unpin a message. Requires PIN_MESSAGES permission.
200 Response:
{
"status": "success",
"data": { "unpinned": true },
"message": "Message unpinned"
}
Errors:
403— Insufficient permissions404— Group or message not found
Channels (/api/channels)
Topic-based community spaces with four visibility modes, invite tokens, and granular role-based moderation. Channels use a shared AES-256-GCM symmetric key encrypted per-member via ECIES, identical to groups.
Endpoints Overview
| Method | Path | Description |
|---|---|---|
| POST | / | Create a channel |
| GET | / | List discoverable channels |
| GET | /:channelId | Get channel metadata |
| PUT | /:channelId | Update channel settings |
| DELETE | /:channelId | Delete a channel |
| POST | /:channelId/join | Join a channel |
| POST | /:channelId/leave | Leave a channel |
| POST | /:channelId/messages | Send a message |
| GET | /:channelId/messages | Get message history |
| GET | /:channelId/messages/search | Search messages |
| POST | /:channelId/invites | Generate an invite token |
| POST | /:channelId/invites/:token/redeem | Redeem an invite token |
| PUT | /:channelId/roles/:memberId | Assign a role |
| POST | /:channelId/messages/:messageId/reactions | Add a reaction |
| DELETE | /:channelId/messages/:messageId/reactions/:reactionId | Remove a reaction |
| PUT | /:channelId/messages/:messageId | Edit a message |
| POST | /:channelId/messages/:messageId/pin | Pin a message |
| DELETE | /:channelId/messages/:messageId/pin | Unpin a message |
| POST | /:channelId/mute/:memberId | Mute a member |
| POST | /:channelId/kick/:memberId | Kick a member |
POST /
Create a new channel.
Request:
{
"name": "general",
"topic": "General discussion",
"visibility": "public"
}
Visibility modes:
| Mode | Listed | Joinable | Description |
|---|---|---|---|
public | Yes | Yes | Anyone can discover and join |
private | Yes | Invite only | Visible in listings but requires invite |
secret | No | Invite only | Not listed, requires invite link |
invisible | No | Invite only | Hidden from non-members entirely |
The name and visibility fields are required. Channel names must be unique, lowercase, and contain no spaces.
201 Response:
{
"status": "success",
"data": {
"id": "channel-uuid",
"name": "general",
"topic": "General discussion",
"visibility": "public",
"creatorId": "member-uuid-1",
"members": [
{ "memberId": "member-uuid-1", "role": "owner", "joinedAt": "2026-03-13T10:00:00.000Z" }
],
"createdAt": "2026-03-13T10:00:00.000Z",
"historyVisibleToNewMembers": true
},
"message": "Channel created"
}
Errors:
400— Missing required fields (name,visibility)409— Channel name already taken
GET /
List channels discoverable by the authenticated member. Public and private channels appear in listings; secret and invisible channels do not.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
cursor | string | Opaque cursor for next page |
limit | number | Results per page |
200 Response:
{
"status": "success",
"data": {
"items": [
{
"id": "channel-uuid",
"name": "general",
"topic": "General discussion",
"visibility": "public",
"memberCount": 42,
"lastMessageAt": "2026-03-13T14:30:00.000Z"
}
],
"cursor": "next-page-cursor",
"hasMore": true
},
"message": "Channels listed"
}
GET /:channelId
Get channel metadata including member list, settings, and pinned messages.
200 Response:
{
"status": "success",
"data": {
"id": "channel-uuid",
"name": "general",
"topic": "General discussion",
"visibility": "public",
"creatorId": "member-uuid-1",
"members": [
{ "memberId": "member-uuid-1", "role": "owner", "joinedAt": "2026-03-13T10:00:00.000Z" }
],
"pinnedMessageIds": ["msg-uuid-1"],
"historyVisibleToNewMembers": true,
"createdAt": "2026-03-13T10:00:00.000Z",
"lastMessageAt": "2026-03-13T14:30:00.000Z"
},
"message": "Channel retrieved"
}
Errors:
403— Not a channel member (for non-public channels)404— Channel not found
PUT /:channelId
Update channel settings. Requires MANAGE_CHANNEL permission.
Request:
{
"name": "general-chat",
"topic": "Updated topic",
"visibility": "private",
"historyVisibleToNewMembers": false
}
All fields are optional. Only provided fields are updated.
200 Response:
{
"status": "success",
"data": {
"id": "channel-uuid",
"name": "general-chat",
"topic": "Updated topic",
"visibility": "private",
"historyVisibleToNewMembers": false
},
"message": "Channel updated"
}
Errors:
403— Missing permission:MANAGE_CHANNEL404— Channel not found409— Channel name already taken
DELETE /:channelId
Delete a channel and all its messages.
200 Response:
{
"status": "success",
"data": { "deleted": true },
"message": "Channel deleted"
}
Errors:
403— Insufficient permissions404— Channel not found
POST /:channelId/join
Join a public channel. Private, secret, and invisible channels require an invite token (use the redeem invite endpoint instead).
200 Response:
{
"status": "success",
"data": { "joined": true },
"message": "Joined channel"
}
Errors:
403— Join denied (channel is not public)404— Channel not found409— Already a member
POST /:channelId/leave
Leave a channel. Triggers key rotation so the departing member cannot decrypt future messages.
200 Response:
{
"status": "success",
"data": { "left": true },
"message": "Left channel"
}
Errors:
403— Not a channel member404— Channel not found
POST /:channelId/messages
Send a message to the channel. The message is encrypted with the channel’s shared symmetric key.
Request:
{
"content": "Welcome everyone!"
}
201 Response:
{
"status": "success",
"data": {
"id": "message-uuid",
"channelId": "channel-uuid",
"senderId": "member-uuid-1",
"encryptedContent": "...",
"createdAt": "2026-03-13T14:30:00.000Z"
},
"message": "Message sent"
}
Errors:
400— Missing required field (content)403— Not a channel member, or member is muted404— Channel not found
GET /:channelId/messages
Get message history with cursor-based pagination.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
cursor | string | Opaque cursor for next page |
limit | number | Results per page |
200 Response:
{
"status": "success",
"data": {
"items": [
{
"id": "message-uuid",
"senderId": "member-uuid-1",
"encryptedContent": "...",
"createdAt": "2026-03-13T14:30:00.000Z",
"editedAt": null,
"pinned": false,
"reactions": []
}
],
"cursor": "next-page-cursor",
"hasMore": true
},
"message": "Messages retrieved"
}
New members see history only if historyVisibleToNewMembers is enabled on the channel.
Errors:
403— Not a channel member404— Channel not found
GET /:channelId/messages/search
Full-text search across channel message history.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
query | string | Search text (required) |
cursor | string | Opaque cursor for next page |
limit | number | Results per page |
200 Response:
{
"status": "success",
"data": {
"items": [
{
"id": "message-uuid",
"senderId": "member-uuid-1",
"encryptedContent": "...",
"createdAt": "2026-03-13T14:30:00.000Z",
"relevanceScore": 0.95
}
],
"cursor": "next-page-cursor",
"hasMore": false
},
"message": "Search results"
}
Errors:
400— Missing required query parameter (query)403— Not a channel member404— Channel not found
POST /:channelId/invites
Generate a time-limited, usage-limited invite token for the channel. Requires CREATE_INVITES permission.
Request:
{
"maxUses": 10,
"expiresInMs": 86400000
}
Both fields are optional. If omitted, the invite has unlimited uses and no expiry.
201 Response:
{
"status": "success",
"data": {
"token": "invite-token-string",
"channelId": "channel-uuid",
"maxUses": 10,
"usesRemaining": 10,
"expiresAt": "2026-03-14T10:00:00.000Z",
"createdBy": "member-uuid-1"
},
"message": "Invite created"
}
Errors:
403— Missing permission:CREATE_INVITES404— Channel not found
POST /:channelId/invites/:token/redeem
Redeem an invite token to join a channel. This is the only way to join private, secret, and invisible channels.
200 Response:
{
"status": "success",
"data": { "redeemed": true },
"message": "Invite redeemed"
}
Errors:
404— Invite token not found409— Already a member410— Invite expired or fully used
PUT /:channelId/roles/:memberId
Assign a role to a channel member. Requires MANAGE_ROLES permission.
Request:
{
"role": "moderator"
}
Available roles: owner, admin, moderator, member
200 Response:
{
"status": "success",
"data": { "memberId": "member-uuid-2", "role": "moderator" },
"message": "Role assigned"
}
Errors:
400— Missing required field (role)403— Missing permission:manage_roles404— Channel not found
POST /:channelId/messages/:messageId/reactions
Add an emoji reaction to a channel message.
Request:
{
"emoji": "🎉"
}
201 Response:
{
"status": "success",
"data": { "reactionId": "reaction-uuid", "emoji": "🎉" },
"message": "Reaction added"
}
Errors:
400— Missing required field (emoji)403— Not a channel member404— Channel or message not found
DELETE /:channelId/messages/:messageId/reactions/:reactionId
Remove a reaction from a channel message.
200 Response:
{
"status": "success",
"data": { "removed": true },
"message": "Reaction removed"
}
Errors:
403— Not the reaction author404— Channel, message, or reaction not found
PUT /:channelId/messages/:messageId
Edit a channel message. Only the original author can edit. Edit history is preserved.
Request:
{
"content": "Updated announcement"
}
200 Response:
{
"status": "success",
"data": {
"id": "message-uuid",
"senderId": "member-uuid-1",
"encryptedContent": "...",
"editedAt": "2026-03-13T15:00:00.000Z",
"editHistory": [
{ "content": "...", "editedAt": "2026-03-13T14:30:00.000Z" }
]
},
"message": "Message edited"
}
Errors:
400— Missing required field (content)403— Not the message author404— Channel or message not found
POST /:channelId/messages/:messageId/pin
Pin a message in the channel. Requires PIN_MESSAGES permission.
200 Response:
{
"status": "success",
"data": { "pinned": true },
"message": "Message pinned"
}
Errors:
403— Insufficient permissions404— Channel or message not found
DELETE /:channelId/messages/:messageId/pin
Unpin a message. Requires PIN_MESSAGES permission.
200 Response:
{
"status": "success",
"data": { "unpinned": true },
"message": "Message unpinned"
}
Errors:
403— Insufficient permissions404— Channel or message not found
POST /:channelId/mute/:memberId
Temporarily mute a member, preventing them from sending messages for the specified duration. Requires MUTE_MEMBERS permission.
Request:
{
"durationMs": 3600000
}
The durationMs field is required and must be a positive number (milliseconds).
200 Response:
{
"status": "success",
"data": {
"muted": true,
"until": "2026-03-13T15:00:00.000Z"
},
"message": "Member muted"
}
Errors:
400— Missing or invalid field (durationMs)403— Missing permission:MUTE_MEMBERS404— Channel not found
POST /:channelId/kick/:memberId
Remove a member from the channel. Triggers key rotation. Requires KICK_MEMBERS permission.
200 Response:
{
"status": "success",
"data": { "kicked": true },
"message": "Member kicked"
}
Errors:
403— Missing permission:KICK_MEMBERS404— Channel not found
Permission System
All group and channel actions are governed by role-based permissions.
Default Roles
| Role | Permissions |
|---|---|
| Owner | All permissions (full control) |
| Admin | Send messages, delete any message, manage members, create invites, pin messages, mute/kick members |
| Moderator | Send messages, delete any message, pin messages, mute/kick members |
| Member | Send messages, delete own messages |
Permission Types
| Permission | Description |
|---|---|
SEND_MESSAGES | Post messages |
DELETE_OWN_MESSAGES | Remove own messages |
DELETE_ANY_MESSAGE | Remove any member’s messages |
MANAGE_MEMBERS | Add/remove members |
MANAGE_ROLES | Assign roles to members |
MANAGE_CHANNEL | Update channel settings (visibility, topic) |
CREATE_INVITES | Generate invite tokens |
PIN_MESSAGES | Pin/unpin messages |
MUTE_MEMBERS | Temporarily prevent members from messaging |
KICK_MEMBERS | Remove members from group/channel |
Encryption Model
Direct Messages
Each message is encrypted with the recipient’s secp256k1 public key using ECIES. No shared keys are required, providing perfect forward secrecy per message.
Groups and Channels
A single AES-256-GCM symmetric key is used per group/channel. This key is encrypted per-member using ECIES:
Shared Key (AES-256-GCM)
↓
ECIES Encrypt for each member
↓
Member A: ECIES(SharedKey, PubKeyA)
Member B: ECIES(SharedKey, PubKeyB)
Member C: ECIES(SharedKey, PubKeyC)
Key Rotation
Key rotation is triggered automatically when:
- A member is removed (by admin/moderator)
- A member voluntarily leaves
- A member is kicked
The rotation process:
- Generate new symmetric key
- Encrypt new key for all remaining members
- Update group/channel metadata
- Broadcast key rotation event via WebSocket
Departed members cannot decrypt messages sent after key rotation.
Real-Time Events
BrightChat delivers real-time updates via WebSocket through the EventNotificationSystem.
Event Types
| Event | Description |
|---|---|
communication:message_sent | New message in any context |
communication:message_edited | Message content updated |
communication:message_deleted | Message removed |
communication:typing_start | Member started typing |
communication:typing_stop | Member stopped typing |
communication:reaction_added | Emoji reaction added |
communication:reaction_removed | Emoji reaction removed |
communication:message_pinned | Message pinned |
communication:message_unpinned | Message unpinned |
communication:member_muted | Member muted |
communication:member_kicked | Member removed |
communication:member_joined | New member added |
communication:member_left | Member departed |
communication:group_created | New group created |
communication:channel_updated | Channel settings changed |
communication:presence_changed | Member status updated |
Presence Status
| Status | Description |
|---|---|
online | Active and available |
offline | Disconnected |
idle | Inactive for configured duration |
dnd | Do not disturb (suppresses notifications) |
Presence changes are broadcast only to members sharing contexts (groups/channels) to prevent enumeration attacks.
Standard Response Format
All BrightChat responses use the IApiEnvelope<T> wrapper:
{
"status": "success",
"data": { ... },
"message": "Human-readable description"
}
Error responses:
{
"status": "error",
"error": {
"code": "NOT_FOUND",
"message": "Group not found"
}
}
Pagination
All list endpoints use cursor-based pagination:
{
"items": [ ... ],
"cursor": "opaque-next-page-cursor",
"hasMore": true
}
Error Codes
| HTTP Status | Code | Condition |
|---|---|---|
201 | — | Resource created (message sent, group created, reaction added) |
200 | — | Successful read or update |
400 | VALIDATION_ERROR | Invalid request payload |
403 | FORBIDDEN | Insufficient permissions or not a member |
404 | NOT_FOUND | Resource not found (also used for privacy-preserving errors) |
409 | ALREADY_EXISTS | Duplicate member or channel name |
410 | GONE | Invite expired or fully used |
500 | INTERNAL_ERROR | Unexpected server error |