Skip to main content

API Reference

This comprehensive API reference covers all available endpoints in the Chirp REST API for developers and integrators.

API Overview

Base URL

Production: https://your-domain.com/api
Development: http://localhost:3001/api

Authentication

Chirp uses bot tokens for API and WebSocket access.

Bot Token

Generate a bot token from User Settings → Developer → Bot Token. Include it in your requests:

Authorization: Bot <your-bot-token>

Bot tokens do not expire. You can regenerate or revoke them from the Developer settings.

Note: Bots must be invited to a server before they can interact with it. See the Bot Development Guide for details.

Rate Limiting

  • General API Endpoints: 2000 requests per minute
  • Authentication Endpoints: 25 requests per 15 minutes (only failed requests count)
  • Admin Endpoints: 10 requests per 15 minutes
  • Auth Status Checks: 500 requests per minute
  • Password Reset: 3 requests per hour
  • Email Verification: 3 requests per 15 minutes

Rate limit info is returned via the standard RateLimit-* headers (RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset). The legacy X-RateLimit-* headers are not used.

When rate limited, the response will be:

{
"error": "Too many requests from this IP, please try again after X minutes."
}

Response Format

Chirp API responses are direct JSON objects — there is no wrapping success/data envelope.

Success responses return the resource directly:

{
"id": "uuid",
"username": "username",
"email": "user@example.com"
}

Or for operations:

{
"success": true,
"message": "Operation successful"
}

Error responses return a simple error string:

{
"error": "Description of what went wrong"
}

Authentication

Register User

POST /auth/register

Creates a new user account. An email verification email is sent — the user must verify before they can log in.

Request Body:

{
"username": "string (required)",
"email": "string (required, valid email)",
"password": "string (required)"
}

Response (201):

{
"message": "Registration successful! Please check your email to verify your account.",
"pending": true
}

Note: No token is returned on registration. The user must verify their email first, then log in.

Error Responses:

  • 400 — Missing required fields
  • 409 — Email already exists or username already taken

Login

POST /auth/login

Authenticates a user. Supports login with email or username.

Request Body:

{
"email": "string (email or username)",
"password": "string",
"twoFactorToken": "string (optional, for 2FA)",
"recoveryCode": "string (optional, for 2FA recovery)"
}

Response (200):

{
"token": "jwt_token_here",
"user": {
"id": "uuid",
"username": "username",
"email": "user@example.com",
"avatar_url": "/uploads/avatars/uuid.webp?t=...",
"status": "online",
"bio": "User bio",
"banner_url": "/uploads/banners/uuid.webp?t=...",
"default_server_notification_type": "all",
"banner_position": 50,
"avatar_crop": "{}",
"date_format": "auto",
"updater_toast_enabled": true
}
}

2FA Flow: If the user has two-factor authentication enabled and no twoFactorToken/recoveryCode is provided, the response will be:

{
"requiresTwoFactor": true,
"message": "2FA verification required"
}

Re-submit the login request with the twoFactorToken or recoveryCode field included.

Error Responses:

  • 400 — Missing email/password
  • 401 — Invalid credentials, unverified email, or invalid 2FA token

Verify Email

GET /auth/verify-email?token=<verification_token>

Verifies a user's email address using the token sent via email.

Response (200):

{
"success": true,
"message": "Email verified successfully! You can now log in to your account."
}

Resend Verification Email

POST /auth/resend-verification

Resends the verification email. Has a 120-second cooldown between requests.

Request Body:

{
"identifier": "string (email or username)"
}

Request Password Reset

POST /auth/request-password-reset

Sends a password reset email. Has a 5-minute cooldown. Always returns the same response regardless of whether the account exists (to prevent enumeration).

Request Body:

{
"identifier": "string (email or username)"
}

Response (200):

{
"success": true,
"message": "If an account with this username or email exists, a password reset email has been sent."
}

Reset Password

POST /auth/reset-password

Completes a password reset using the token from the reset email.

Request Body:

{
"token": "string (from reset email)",
"newPassword": "string (min 6 chars)"
}

Refresh Token

POST /auth/refresh

Headers:

Authorization: Bearer <current-jwt-token>

Returns a new JWT with a fresh 30-day expiration.

Response (200):

{
"token": "new_jwt_token_here"
}

Logout

POST /auth/logout

Headers:

Authorization: Bearer <jwt-token>

Sets the user's status to offline.

Response (200):

{
"success": true
}

Get Current User

GET /auth/me

Returns the currently authenticated user's profile.

Response (200):

{
"id": "uuid",
"username": "username",
"email": "user@example.com",
"avatar_url": "/uploads/avatars/uuid.webp?t=...",
"status": "online",
"intended_status": "online",
"custom_status": "Working on something cool",
"bio": "User biography",
"birthday": "2000-01-15",
"banner_url": "/uploads/banners/uuid.webp?t=...",
"default_server_notification_type": "all",
"banner_position": 50,
"avatar_crop": "{}",
"nsfw_blur_enabled": true,
"date_format": "auto",
"updater_toast_enabled": true,
"advanced_noise_suppression": false,
"update_channel": "stable"
}

Upload Avatar

POST /auth/me/avatar

Uploads a new user avatar. Accepts JPEG, PNG, GIF, or WebP. Images are resized to 100×100. GIFs preserve animation.

Request Body (multipart/form-data):

avatar: file (required)
crop: JSON string (optional) — { "x": 0, "y": 0, "width": 100, "height": 100 }

Response (200): Returns the updated user object.


Upload Banner

POST /auth/me/banner

Uploads a new user banner. Images are resized to 600×240.

Request Body (multipart/form-data):

banner: file (required)
crop: JSON string (optional)

Response (200): Returns the updated user object.


Change Password

POST /auth/me/password

Changes the authenticated user's password.

Request Body:

{
"currentPassword": "string (required)",
"newPassword": "string (required, min 6 chars)"
}

Users

Get All Users

GET /users

Returns all non-deleted users. Invisible users appear as offline to others.

Response (200):

[
{
"id": "uuid",
"username": "username",
"email": "user@example.com",
"avatar_url": "/uploads/avatars/uuid.webp",
"status": "online"
}
]

Update User Profile

PATCH /users/me

Updates the authenticated user's profile fields. Only the specified fields are updated.

Request Body (all fields optional):

{
"avatar_url": "string",
"bio": "string (max 190 chars)",
"birthday": "YYYY-MM-DD or null",
"status": "online | idle | dnd | invisible",
"custom_status": "string (max 128 chars)",
"status_expires_at": "ISO datetime or null",
"custom_status_expires_at": "ISO datetime or null",
"default_server_notification_type": "all | pings_only | none",
"banner_position": "number (0-100)",
"avatar_crop": "{ x, y, width, height }",
"nsfw_blur_enabled": "boolean",
"date_format": "auto | us | uk | iso | eu | ca | jp",
"updater_toast_enabled": "boolean",
"advanced_noise_suppression": "boolean",
"update_channel": "stable | nightly"
}

Response (200): Returns the updated user object.


Server Order

GET /users/me/server-order
PUT /users/me/server-order

Get or update the user's custom server ordering.

PUT Request Body:

{
"serverOrder": ["server_id_1", "server_id_2", "server_id_3"]
}

Account Deletion

POST /users/me/request-deletion
POST /users/me/cancel-deletion
DELETE /users/me/account
GET /users/me/deletion-status

Manage account deletion. Users cannot delete accounts while they own servers.

Request Deletion Body:

{
"mode": "regular | nuke",
"delay": true // optional, schedules deletion 7 days out
}

Execute Deletion Body:

{
"confirmUsername": "string (must match current username)",
"mode": "regular | nuke (if no pending request)"
}

User Nicknames

GET /users/me/nicknames
PUT /users/me/nicknames/:targetUserId
DELETE /users/me/nicknames/:targetUserId

Manage personal nicknames for other users (max 32 chars).


Servers

Get User Servers

GET /servers

Returns all servers the authenticated user is a member of.


Create Server

POST /servers

Request Body:

{
"name": "string (required)"
}

Update Server

PATCH /servers/:serverId

Requires Permission: manage_server (role-based) or server owner


Delete Server

DELETE /servers/:serverId

Requires: Server owner only


Server Icon & Banner

POST /servers/:serverId/icon
POST /servers/:serverId/banner
DELETE /servers/:serverId/banner

Upload or remove server icon/banner images.


Invites

POST /servers/:serverId/regenerate-invite
GET /servers/invites/:inviteCode
POST /servers/join

Join Server Body:

{
"inviteCode": "string"
}

Leave Server

POST /servers/:serverId/leave

Channels

Get Server Channels

GET /servers/:serverId/channels

Create Channel

POST /servers/:serverId/channels

Request Body:

{
"name": "string (required)",
"type": "text | voice | media (default: text)",
"isPrivate": "boolean (optional)",
"category": "string (optional)"
}

Edit Channel

PATCH /servers/:serverId/channels/:channelId

Delete Channel

DELETE /servers/:serverId/channels/:channelId

Reorder Channels

PUT /servers/:serverId/channels/reorder

Channel Encryption Info

GET /servers/channels/:channelId/encryption-info

Categories

GET /servers/:serverId/categories
POST /servers/:serverId/categories
PUT /servers/:serverId/categories/reorder
PUT /servers/:serverId/categories/:categoryName
DELETE /servers/:serverId/categories/:categoryName

Manage server channel categories.


Server Profiles

PUT /servers/:serverId/profile
POST /servers/:serverId/profile/avatar
POST /servers/:serverId/profile/banner
DELETE /servers/:serverId/profile/reset

Manage server-specific user profiles (per-server nicknames, avatars, banners).


Members

Get Server Members

GET /servers/:serverId/members

Get Channel Members

GET /servers/:serverId/channels/:channelId/members

Messages

Get Channel Messages

GET /channels/:channelId/messages

Query Parameters:

  • limit — Number of messages (default: 50)
  • before — Get messages before this message ID

Send Message

POST /channels/:channelId/messages

Supports text content, file attachments (multipart/form-data), embeds, replies, and polls.

Request Body (JSON or form-data):

{
"content": "string (max 4000 chars)",
"replyTo": "message_id (optional)",
"embed": { "title": "string", "description": "string", "color": "string" },
"poll": {
"question": "string",
"options": ["option1", "option2"],
"expires_at": "ISO datetime (optional)",
"allow_multiple": false
}
}

For file attachments, use multipart/form-data with field name attachments.


Edit Message

PATCH /messages/:messageId

Note: This endpoint is not nested under /channels/:channelId/. It is mounted at /api/messages/:messageId.

Request Body:

{
"content": "string"
}

Delete Message

DELETE /messages/:messageId

Note: This endpoint is not nested under /channels/:channelId/. It is mounted at /api/messages/:messageId.


Delete Message Attachment

DELETE /messages/:messageId/attachments/:attachmentIndex

Poll Voting

POST /messages/:messageId/poll/vote
DELETE /messages/:messageId/poll/vote

Vote Body:

{
"optionIndex": 0
}

Reactions

Toggle Reaction (Server Messages)

POST /messages/:messageId/reactions

Adds or removes a reaction on a server message. If the user already has this reaction, it is removed; otherwise, it is added.

Request Body:

{
"emoji": "👍"
}

Response (200):

{
"reactions": {
"👍": {
"users": ["user_id_1", "user_id_2"],
"emoji": "👍",
"metadata": null
}
}
}

Toggle Reaction (DM Messages)

POST /dm/:messageId/reactions

Same as above but for direct messages.


Threads

Create Thread

POST /threads/create

Request Body:

{
"channelId": "uuid (required)",
"messageId": "uuid (required)",
"name": "string (required)"
}

Join Thread

POST /threads/:threadId/join

Leave Thread

POST /threads/:threadId/leave

Get Server Threads

GET /servers/:serverId/threads

Get Thread Details

GET /threads/:threadId/details

Get Thread Participants

GET /threads/:threadId/participants

Lock Thread

POST /threads/:threadId/lock

Reopen Thread

POST /threads/:threadId/reopen

Delete Thread

DELETE /threads/:threadId

Auto-Archive & Cleanup

POST /threads/auto-archive
POST /threads/cleanup

Media and Files

Upload Media

POST /channels/:channelId/media

Uploads a file to a channel's media gallery.

Request Body (multipart/form-data):

media: file (required)

Get Channel Media

GET /channels/:channelId/media

Rename Media

PUT /media/:mediaId/rename

Delete Media

DELETE /media/:mediaId

Move Media to Folder

PUT /media/:mediaId/move

Media Video Info & Download

POST /channels/:channelId/media/video-info
POST /channels/:channelId/media/video-download

Serve File / Thumbnail

GET /media/files/:filename
GET /media/files/thumbnails/:filename

Media Comments

POST /media/:mediaId/comments
GET /media/:mediaId/comments
PUT /media/comments/:commentId
DELETE /media/comments/:commentId

Media Reactions

POST /media/:mediaId/reactions

Folders

GET /channels/:channelId/folders
POST /channels/:channelId/folders
PUT /media/folders/:folderId
DELETE /media/folders/:folderId

Direct Messages

Get DM Conversations

GET /direct-messages

Returns a list of conversations the user has participated in.


Get DM Messages

GET /dms/:otherUserId/messages

Query Parameters:

  • limit — Number of messages
  • before — Get messages before this message ID

Send DM

POST /dms/:receiverId/messages

Supports text, attachments, replies, and polls similar to channel messages.


Delete DM Message

DELETE /direct-messages/:messageId

Delete DM Attachment

DELETE /direct-messages/:messageId/attachments/:attachmentIndex

Edit DM Message

PATCH /direct-messages/:messageId

DM Poll Voting

POST /direct-messages/:messageId/poll/vote
DELETE /direct-messages/:messageId/poll/vote

Group DM Messages

DELETE /group-dm-messages/:messageId

Roles

Get Server Roles

GET /servers/:serverId/roles

Create Role

POST /servers/:serverId/roles

Update Role

PATCH /servers/:serverId/roles/:roleId

Delete Role

DELETE /servers/:serverId/roles/:roleId

Reorder Roles

PATCH /servers/:serverId/roles/reorder

Assign Role to Member

POST /servers/:serverId/members/:userId/roles/:roleId

Remove Role from Member

DELETE /servers/:serverId/members/:userId/roles/:roleId

Get Member Roles

GET /servers/:serverId/members/:userId/roles

Check Permissions

GET /servers/:serverId/permissions/check
POST /servers/:serverId/permissions/batch
GET /servers/permissions

Moderation

Kick Member

POST /servers/:serverId/kick/:userId

Request Body:

{
"reason": "string (optional)"
}

Ban Member

POST /servers/:serverId/ban/:userId

Request Body:

{
"reason": "string (optional)"
}

Unban Member

DELETE /servers/:serverId/ban/:userId

Unkick (Delete Kick Record)

DELETE /servers/:serverId/kick/:userId

Get Kicks

GET /servers/:serverId/kicks

Get Bans

GET /servers/:serverId/bans

Get Admin Logs

GET /servers/:serverId/admin-logs

Returns the moderation/audit log for a server.


Search Messages

POST /search

Searches messages across server channels or DMs.

Request Body:

{
"query": "search text",
"serverId": "uuid or 'home' for DMs",
"channelId": "uuid (optional)",
"filters": {
"from": "username (optional)",
"mentions": "username (optional)",
"in": "channel name (optional)",
"has": "file | image | link | embed (optional)"
},
"limit": 25,
"offset": 0
}

Response (200):

{
"results": [
{
"id": "uuid",
"content": "Message content",
"timestamp": "2024-01-01T00:00:00.000Z",
"username": "author",
"avatar_url": "/uploads/avatars/uuid.webp",
"message_type": "server",
"channel_name": "general",
"channel_id": "uuid",
"server_id": "uuid",
"user_id": "uuid",
"attachments": [],
"highlighted_content": "Message <mark>content</mark>"
}
],
"total": 1,
"hasMore": false
}

Search Suggestions

GET /search/suggestions?serverId=uuid&type=users|channels

Returns autocomplete suggestions for search filters.


Webhooks

Get Channel Webhooks

GET /webhooks/channel/:channelId

Requires Permission: manage_channels


Create Webhook

POST /webhooks/channel/:channelId

Requires Permission: manage_channels

Request Body:

{
"name": "string (required, max 80 chars)",
"avatar_url": "string (optional)",
"allow_username_override": "boolean (optional)",
"allow_avatar_override": "boolean (optional)"
}

Response (201):

{
"id": "uuid",
"channel_id": "uuid",
"created_by": "user_uuid",
"name": "My Webhook",
"avatar_url": null,
"token": "64-char-hex-token",
"active": true,
"allow_username_override": false,
"allow_avatar_override": false,
"created_by_username": "creator_username"
}

Update Webhook

PUT /webhooks/:webhookId

Delete Webhook

DELETE /webhooks/:webhookId

Upload Webhook Avatar

POST /webhooks/:webhookId/avatar

Execute Webhook

POST /webhooks/:token/execute

This is a public endpoint — no authentication required. The webhook token serves as auth.

Request Body:

{
"content": "string (required, max 2000 chars)",
"username": "string (optional, if allow_username_override is true)",
"avatar_url": "string (optional, if allow_avatar_override is true)"
}

Response (200):

{
"message": "Message sent successfully",
"id": "message_uuid"
}

Friends

Get Friends

GET /friends

Send Friend Request

POST /friends/request

Accept/Reject Friend Request

PUT /friends/request/:requestId

Remove Friend

DELETE /friends/:friendId

Cancel Friend Request

DELETE /friends/request/:requestId

Admin Endpoints

Notify Update

POST /admin/notify-update

Migrate Thumbnails

POST /admin/migrate-thumbnails

Get Thumbnail Stats

GET /admin/thumbnail-stats

Get Server Version

GET /admin/version

Pins

Pin/Unpin Message (Server)

POST /messages/:messageId/pin
DELETE /messages/:messageId/pin

Pin/Unpin Message (DM)

POST /dm/:messageId/pin
DELETE /dm/:messageId/pin

Pin/Unpin Message (Group DM)

POST /group-dm/:messageId/pin
DELETE /group-dm/:messageId/pin

Get Pinned Messages

GET /channels/:channelId/pins
GET /dm/:otherUserId/pins
GET /group-dm/:groupDMId/pins

Get Unread Pin Count

GET /channels/:channelId/pins/unread-count
GET /dm/:otherUserId/pins/unread-count
GET /group-dm/:groupDMId/pins/unread-count

Custom Emoji

Get Emojis

GET /emojis/user/:userId
GET /emojis/server/:serverId
GET /emojis/available

Upload Emoji

POST /emojis/user
POST /emojis/server/:serverId

Delete Emoji

DELETE /emojis/user/:emojiId
DELETE /emojis/server/:serverId/:emojiId

Resolve Emojis

POST /emojis/resolve
POST /emojis/resolve-by-name

Stickers

Get Stickers

GET /stickers/user/:userId
GET /stickers/server/:serverId
GET /stickers/available

Upload Sticker

POST /stickers/user
POST /stickers/server/:serverId

Delete Sticker

DELETE /stickers/user/:stickerId
DELETE /stickers/server/:serverId/:stickerId

Resolve Stickers

POST /stickers/resolve

Events

Get Server Events

GET /servers/:serverId/events

Create Event

POST /servers/:serverId/events

Update Event

PUT /servers/:serverId/events/:eventId

Delete Event

DELETE /servers/:serverId/events/:eventId

Toggle Interest / Get Interested Users

POST /servers/:serverId/events/:eventId/interest
GET /servers/:serverId/events/:eventId/interested

Notes

GET /notes
POST /notes
PUT /notes/:id
DELETE /notes/:id
GET /notes/search

Personal notes — only visible to the authenticated user.


Badges

Get User Badges

GET /users/:userId/badges
GET /users/me/badges

Award / Remove Badge (Admin)

POST /users/:userId/badges
POST /badges/auto-award
DELETE /users/:userId/badges/:badgeType

Favorites

Emoji Favorites

GET /favorites/emojis
POST /favorites/emojis
DELETE /favorites/emojis/:type/:identifier
GET /favorites/emojis/check/:type/:identifier

Sticker Favorites

GET /favorites/stickers
POST /favorites/stickers
DELETE /favorites/stickers/:stickerId
GET /favorites/stickers/check/:stickerId

GIFs

GET /gifs/search
GET /gifs/trending
GET /gifs/categories
GET /gifs/favorites
POST /gifs/favorites
DELETE /gifs/favorites/:tenorId
GET /gifs/favorites/check/:tenorId

Group DMs

List Group DMs

GET /group-dms

Create Group DM

POST /group-dms

Get / Send Messages

GET /group-dms/:groupDMId/messages
POST /group-dms/:groupDMId/messages

Edit / Delete Messages

PATCH /group-dms/:groupDMId/messages/:messageId
DELETE /group-dms/:groupDMId/messages/:messageId

Manage Members

POST /group-dms/:groupDMId/members
DELETE /group-dms/:groupDMId/members/:memberId

Get Details / Leave

GET /group-dms/:groupDMId
POST /group-dms/:groupDMId/leave

Two-Factor Authentication

GET /2fa/status
POST /2fa/setup
POST /2fa/verify
POST /2fa/disable
POST /2fa/regenerate-codes

Bot Tokens

Get Bot Info

GET /bot-tokens
GET /bot-tokens/:botId

Create / Regenerate / Revoke

POST /bot-tokens
POST /bot-tokens/regenerate
DELETE /bot-tokens

Bot Profile

PATCH /bot-tokens/profile
POST /bot-tokens/avatar

Bot Server Management

GET /bot-tokens/servers
POST /bot-tokens/servers/join
POST /bot-tokens/servers/:serverId/leave

Channel Mutes

GET /channel-mutes
GET /channel-mutes/:channelId
POST /channel-mutes/:channelId
DELETE /channel-mutes/:channelId

Channel Settings (Per-User)

GET /channel-settings/:channelId
PUT /channel-settings/:channelId
GET /channel-settings/server/:serverId

Server Settings (Per-User)

GET /server-settings
GET /server-settings/:serverId
PUT /server-settings/:serverId

Channel Subscriptions (Announcements)

GET /channels/:channelId/subscriptions
GET /channels/:channelId/subscription-status
POST /channels/:channelId/subscribe
DELETE /channels/:sourceChannelId/subscriptions/:targetChannelId
GET /servers/:serverId/channels/subscribable

Status

GET /status/me
PUT /status/me
PUT /status/me/custom
DELETE /status/me/custom
POST /status/me/activity

Get WebRTC Config

GET /status/webrtc-config

Returns the TURN/STUN server configuration for voice channels.


POST /link-preview

Fetches OpenGraph and oEmbed data for a URL. See the Rich Link Previews guide for oEmbed integration details.


Web Push Notifications

GET /web-push/vapid-key
POST /web-push/subscribe
POST /web-push/unsubscribe

Mobile Push (FCM)

POST /fcm/register-token
POST /fcm/deactivate-token
GET /fcm/user-tokens/:userId

Collaborative Documents

Get / Create Documents

GET /collaborative/:channelId/documents
POST /collaborative/:channelId/documents

Get / Update / Delete Document

GET /collaborative/:channelId/documents/:documentId
PATCH /collaborative/:channelId/documents/:documentId
DELETE /collaborative/:channelId/documents/:documentId

Document Locking

POST /collaborative/:channelId/documents/:documentId/lock
DELETE /collaborative/:channelId/documents/:documentId/lock

Upload Attachment

POST /collaborative/:channelId/documents/:documentId/upload

Read State (Last Seen)

POST /last-seen/channel/:channelId
POST /last-seen/dm/:otherUserId
POST /last-seen/group-dm/:groupDMId
GET /last-seen
GET /last-seen/channels
GET /last-seen/dms
GET /last-seen/group-dms
GET /last-seen/missed-count
GET /last-seen/missed-messages
POST /last-seen/mark-server-read/:serverId
POST /last-seen/mark-all-read

Error Codes

HTTP StatusDescription
400Bad request — invalid input data or missing required fields
401Unauthorized — authentication required or invalid credentials
403Forbidden — insufficient permissions
404Not found — resource does not exist
409Conflict — resource already exists
429Rate limited — too many requests
500Internal server error

WebSocket Events

Chirp uses Socket.IO for real-time communication, not raw WebSocket.

Connection

import { io } from 'socket.io-client';

const socket = io('http://localhost:3001', {
auth: {
token: 'Bot <your-bot-token>'
}
});

The bot token is passed via the auth.token handshake option with the Bot prefix. On successful connection, the server automatically:

  • Joins the user to their personal room (user:<userId>)
  • Joins the user to all their servers' channels (where they have view_channels permission)
  • Joins the user to their group DMs
  • Sets their status to online (or their intended status)

Client → Server Events

heartbeat

Send periodically to maintain online status. The server uses heartbeats for idle/offline detection.

socket.emit('heartbeat');

typing:start / typing:stop

socket.emit('typing:start', {
channelId: 'channel_uuid',
isDM: false,
isGroupDM: false
});

channel:join / channel:leave

Dynamically join/leave channel rooms for real-time updates.

socket.emit('channel:join', 'channel_uuid');
socket.emit('channel:leave', 'channel_uuid');

channel:read / dm:read / group-dm:read

Sync read state across devices.

socket.emit('channel:read', { channelId: 'uuid', timestamp: new Date().toISOString() });
socket.emit('dm:read', { channelId: 'uuid', otherUserId: 'uuid' });

join-voice-channel

socket.emit('join-voice-channel', { channelId: 'voice_channel_uuid' });

Server → Client Events

message:new

Emitted when a new message is created in a channel the user has joined.

{
"id": "uuid",
"channel_id": "uuid",
"user_id": "uuid",
"content": "Hello world!",
"username": "username",
"avatar_url": "/uploads/avatars/uuid.webp",
"created_at": "2024-01-01T00:00:00.000Z",
"server_id": "uuid"
}

dm:new

Emitted when a new direct message is received.

{
"id": "uuid",
"sender_id": "uuid",
"receiver_id": "uuid",
"content": "Hello private world!",
"created_at": "2024-01-01T00:00:00.000Z",
"sender": {
"username": "sender_username",
"avatar_url": "/uploads/avatars/uuid.webp"
}
}

message:updated

Emitted when a message is edited.

message:deleted

Emitted when a message is deleted.

{
"messageId": "uuid",
"channelId": "uuid"
}

typing:user

Emitted when a user starts/stops typing in a server channel.

{
"channelId": "uuid",
"userId": "uuid",
"username": "username",
"isTyping": true
}

typing:dm

Emitted for DM typing indicators.

{
"userId": "uuid",
"username": "username",
"isTyping": true
}

user:status

Emitted when a user's presence status changes.

{
"userId": "uuid",
"status": "online"
}

user:profile_updated

Emitted when a user updates their profile.

{
"userId": "uuid",
"updates": {
"avatar_url": "/uploads/avatars/uuid.webp?t=..."
}
}

reaction:updated

Emitted when reactions on a message change.

{
"messageId": "uuid",
"reactions": {},
"channelId": "uuid"
}

read-state:updated

Sync read state across multiple devices.


SDKs and Libraries

Official SDK

  • @chirp-dev/chirp-sdk — Bot development SDK with WebSocket handling, command registration, and TypeScript support

Happy Building!