--- # SPDX-License-Identifier: AGPL-3.0-or-later title: Thread members description: Thread member objects, joining and leaving threads, member lists, and thread notification settings. --- import RouteHeader from '@/components/RouteHeader.astro'; A thread member records that a user joined a [thread](/http-api/threads/). A thread holds at most 1,000 members, and adding one more returns 400 `MAX_THREAD_MEMBERS`. :::note[User requests need the `channel_threads` client capability] A request from a user without the [`channel_threads` client capability](/http-api/threads/#client-capability) returns 404 `NOT_FOUND`. [Get thread member](#get-thread-member) and [List thread members](#list-thread-members) return 404 `NOT_FOUND` to every user. A `channel_id` that does not exist or names a channel outside a guild returns the same 404. ::: A route on this page returns 403 `MISSING_PERMISSIONS` when the caller is not a member of the guild, unless its own entry states an earlier result. A guild channel that is not a thread and that the caller cannot view also returns 403 `MISSING_PERMISSIONS`. A thread whose parent channel no longer exists returns 404 `UNKNOWN_CHANNEL`. ## Thread member object ### Structure | Field | Type | Description | | --- | --- | --- | | id?1 | snowflake | The ID of the thread | | user_id?1 | snowflake | The ID of the user | | join_timestamp | ISO8601 timestamp | The time the user last joined the thread | | flags | integer | The [thread member flags](#thread-member-flags) | | muted?2 | boolean | Whether the user muted the thread | | mute_config?2 | ?[guild mute configuration](/http-api/users/settings/#guild-mute-configuration-object) object | The mute expiry of the thread, or null when none is stored | | member?3 | [guild member](/http-api/guild-members/#guild-member-object) object | The guild member of the user | 1 Omitted on the `member` of a thread in [Ready](/gateway/events/#ready), [Guild Create](/gateway/events/#guild-create), and [Guild Sync](/gateway/events/#guild-sync) 2 Present only on the caller's own membership 3 In an HTTP response, present only when the request sets `with_member` and the user is still a guild member. [Thread Members Update](/gateway/threads/#thread-members-update) defines it on each `added_members` entry ### Example ```json { "id": "1501320100000000000", "user_id": "1501314428688992222", "join_timestamp": "2026-05-05T20:30:05.018Z", "flags": 3, "muted": false, "mute_config": null } ``` ## Thread member flags | Value | Name | Description | | --- | --- | --- | | 1 << 0 | HAS_INTERACTED1 | The user sent a message in the thread or created it | | 1 << 1 | ALL_MESSAGES | Notify the user of every message in the thread | | 1 << 2 | ONLY_MENTIONS | Notify the user only of mentions in the thread | | 1 << 3 | NO_MESSAGES | Notify the user of nothing in the thread | 1 Set only by Fluxer. A bot that creates a thread starts without it At most one of the three notification flags is set. With none set, the thread follows the notification level of its parent. A member keeps the membership after losing access to the parent. Removal from the guild removes every membership in its threads. Fluxer emits a [Thread Members Update](/gateway/threads/#thread-members-update) for each of them. ## Join thread Adds the caller to a thread. Returns 204 with no body. Emits a [Thread Members Update](/gateway/threads/#thread-members-update) Gateway event. ### Limitations - The caller must be able to view the thread. - The thread must not be archived. - A locked thread requires a thread moderator. Joining a thread the caller already belongs to runs the checks above, then returns 204 and changes nothing. Each session of a newly added user receives [Thread Create](/gateway/threads/#thread-create) when it has [thread access](/gateway/threads/#session-flag) and can view the thread. A session still connecting to the guild receives none. Joining a locked thread needs an enrolled authenticator while the guild [MFA level](/http-api/guilds/#mfa-levels) is elevated, unless the caller owns the guild. ### Path parameters | Field | Type | Description | | --- | --- | --- | | channel_id | snowflake | The ID of the thread | ### Response | Status | Body | Condition | | --- | --- | --- | | 204 | empty | Caller is a member | | 400 | [error response](/http-api/#error-response) | Channel is not a thread and the request returns `INVALID_CHANNEL_TYPE` | | 400 | [error response](/http-api/#error-response) | Thread is archived and the request returns `THREAD_ARCHIVED` | | 400 | [error response](/http-api/#error-response) | Thread is locked and the caller is not a thread moderator, returning `THREAD_LOCKED` | | 400 | [error response](/http-api/#error-response) | Thread has 1,000 members and the request returns `MAX_THREAD_MEMBERS` | | 400 | [error response](/http-api/#error-response) | Caller needs an authenticator and the request returns `TWO_FACTOR_REQUIRED` | | 403 | [error response](/http-api/#error-response) | Caller cannot view the thread and the request returns `MISSING_ACCESS` | ### Rate limit 10 requests per 10 seconds for each authenticated user and channel ID, on the `channel:thread:member:put::channel_id` bucket. ## Add thread member Adds another guild member to a thread. Requires `SEND_MESSAGES_IN_THREADS`. Returns 204 with no body. Emits a [Thread Members Update](/gateway/threads/#thread-members-update) Gateway event. ### Limitations - The caller must be able to view the thread. - The thread must not be archived. - A locked thread requires a thread moderator. - A private thread with `invitable` false requires the caller or the target to be a thread moderator. - The target must be a guild member who can view the parent. `user_id` of `@me` behaves as [Join thread](#join-thread). A request that names the caller's own ID runs the checks above, and Fluxer posts no message for it. Adding a user who is already a member runs the checks above, then returns 204 and changes nothing. Each session of a newly added user receives [Thread Create](/gateway/threads/#thread-create) when it has [thread access](/gateway/threads/#session-flag) and can view the thread. A session still connecting to the guild receives none. Adding to a locked thread needs an enrolled authenticator while the guild [MFA level](/http-api/guilds/#mfa-levels) is elevated, unless the caller owns the guild. Adding a target who is not a thread moderator to a private thread with `invitable` false needs one too. ### Path parameters | Field | Type | Description | | --- | --- | --- | | channel_id | snowflake | The ID of the thread | | user_id | snowflake | The ID of the user to add | ### Response | Status | Body | Condition | | --- | --- | --- | | 204 | empty | Target is a member | | 400 | [error response](/http-api/#error-response) | Channel is not a thread and the request returns `INVALID_CHANNEL_TYPE` | | 400 | [error response](/http-api/#error-response) | Thread is archived and the request returns `THREAD_ARCHIVED` | | 400 | [error response](/http-api/#error-response) | Thread is locked and the caller is not a thread moderator, returning `THREAD_LOCKED` | | 400 | [error response](/http-api/#error-response) | Thread has 1,000 members and the request returns `MAX_THREAD_MEMBERS` | | 400 | [error response](/http-api/#error-response) | Caller needs an authenticator and the request returns `TWO_FACTOR_REQUIRED` | | 403 | [error response](/http-api/#error-response) | Caller cannot view the thread and the request returns `MISSING_ACCESS` | | 403 | [error response](/http-api/#error-response) | Caller lacks `SEND_MESSAGES_IN_THREADS` and the request returns `MISSING_PERMISSIONS` | | 403 | [error response](/http-api/#error-response) | Neither user is a thread moderator in a private thread that is not `invitable`, returning `MISSING_PERMISSIONS` | | 403 | [error response](/http-api/#error-response) | Target cannot view the parent and the request returns `MISSING_ACCESS` | | 403 | [error response](/http-api/#error-response) | Caller is timed out and the request returns `COMMUNICATION_DISABLED` | | 404 | [error response](/http-api/#error-response) | Target is not a guild member and the request returns `UNKNOWN_MEMBER` | ### Side effects Adding another user posts a `RECIPIENT_ADD` message in the thread that mentions the target. Fluxer emits [Message Create](/gateway/events/#message-create) for it. ### Rate limit 10 requests per 10 seconds for each authenticated user and channel ID, on the `channel:thread:member:put::channel_id` bucket. ## Leave thread Removes the caller from a thread. Returns 204 with no body. Emits a [Thread Members Update](/gateway/threads/#thread-members-update) Gateway event. A timed-out member can leave a thread. A member who can no longer view the thread receives 403 `MISSING_ACCESS`. ### Path parameters | Field | Type | Description | | --- | --- | --- | | channel_id | snowflake | The ID of the thread | ### Response | Status | Body | Condition | | --- | --- | --- | | 204 | empty | Caller left the thread | | 400 | [error response](/http-api/#error-response) | Channel is not a thread and the request returns `INVALID_CHANNEL_TYPE` | | 400 | [error response](/http-api/#error-response) | Thread is archived and the request returns `THREAD_ARCHIVED` | | 403 | [error response](/http-api/#error-response) | Caller cannot view the thread and the request returns `MISSING_ACCESS` | | 404 | [error response](/http-api/#error-response) | Caller is not a member and the request returns `UNKNOWN_THREAD_MEMBER` | ### Rate limit 10 requests per 10 seconds for each authenticated user and channel ID, on the `channel:thread:member:delete::channel_id` bucket. ## Remove thread member Removes a member from a thread. Requires `MANAGE_THREADS`, or ownership of a private thread. Returns 204 with no body. Emits a [Thread Members Update](/gateway/threads/#thread-members-update) Gateway event. ### Limitations - The caller must be able to view the thread. - The thread must not be archived. - The caller must be a [thread moderator](/http-api/threads/#thread-moderators) or the owner of the private thread. `user_id` of `@me` or of the caller behaves as [Leave thread](#leave-thread). Removing a member needs an enrolled authenticator while the guild [MFA level](/http-api/guilds/#mfa-levels) is elevated, unless the caller owns the guild or the private thread. ### Path parameters | Field | Type | Description | | --- | --- | --- | | channel_id | snowflake | The ID of the thread | | user_id | snowflake | The ID of the user to remove | ### Response | Status | Body | Condition | | --- | --- | --- | | 204 | empty | Member was removed | | 400 | [error response](/http-api/#error-response) | Channel is not a thread and the request returns `INVALID_CHANNEL_TYPE` | | 400 | [error response](/http-api/#error-response) | Thread is archived and the request returns `THREAD_ARCHIVED` | | 400 | [error response](/http-api/#error-response) | Caller needs an authenticator and the request returns `TWO_FACTOR_REQUIRED` | | 403 | [error response](/http-api/#error-response) | Caller cannot view the thread and the request returns `MISSING_ACCESS` | | 403 | [error response](/http-api/#error-response) | Caller is neither a thread moderator nor the owner of the private thread and the request returns `MISSING_PERMISSIONS` | | 403 | [error response](/http-api/#error-response) | Caller is timed out and the request returns `COMMUNICATION_DISABLED` | | 404 | [error response](/http-api/#error-response) | Target is not a member and the request returns `UNKNOWN_THREAD_MEMBER` | ### Side effects Removing another user posts a `RECIPIENT_REMOVE` message in the thread that mentions the target. Fluxer emits [Message Create](/gateway/events/#message-create) for it. ### Rate limit 10 requests per 10 seconds for each authenticated user and channel ID, on the `channel:thread:member:delete::channel_id` bucket. ## Get thread member Returns the [thread member object](#thread-member-object) of a user. Requires a bot token. ### Path parameters | Field | Type | Description | | --- | --- | --- | | channel_id | snowflake | The ID of the thread | | user_id | snowflake | The ID of the user | ### Query parameters | Field | Type | Description | | --- | --- | --- | | with_member? | boolean | Whether to include the guild member of the user (default false) | ### Response | Status | Body | Condition | | --- | --- | --- | | 200 | [thread member](#thread-member-object) object | Member was returned | | 400 | [error response](/http-api/#error-response) | Channel is not a thread and the request returns `INVALID_CHANNEL_TYPE` | | 403 | [error response](/http-api/#error-response) | Caller cannot view the thread and the request returns `MISSING_ACCESS` | | 404 | [error response](/http-api/#error-response) | User is not a member and the request returns `UNKNOWN_THREAD_MEMBER` | | 404 | [error response](/http-api/#error-response) | Caller is a user and the request returns `NOT_FOUND` | ### Rate limit 40 requests per 10 seconds for each authenticated user and channel ID, on the `channel:thread:member:get::channel_id` bucket. ## List thread members Returns the [thread member objects](#thread-member-object) of a thread in ascending user ID order. Requires a bot token. A user client reads member lists through the `thread_member_lists` option of [Lazy Request](/gateway/commands/#lazy-request). ### Path parameters | Field | Type | Description | | --- | --- | --- | | channel_id | snowflake | The ID of the thread | ### Query parameters | Field | Type | Description | | --- | --- | --- | | with_member? | boolean | Whether to include the guild member of each thread member (default false) | | after? | snowflake | Return members with a user ID above this one | | limit? | integer | The maximum number of members to return (1-100, default 100) | ### Response | Status | Body | Condition | | --- | --- | --- | | 200 | array[[thread member](#thread-member-object) object] | Members were returned | | 400 | [error response](/http-api/#error-response) | Channel is not a thread and the request returns `INVALID_CHANNEL_TYPE` | | 403 | [error response](/http-api/#error-response) | Caller cannot view the thread and the request returns `MISSING_ACCESS` | | 404 | [error response](/http-api/#error-response) | Caller is a user and the request returns `NOT_FOUND` | ### Rate limit 20 requests per 10 seconds for each authenticated user and channel ID, on the `channel:thread:members:list::channel_id` bucket. ## Modify thread member settings Changes the caller's notification settings for a thread they joined. User-only. Returns the updated [thread member object](#thread-member-object), or 204 when nothing changed. Emits a [Thread Member Update](/gateway/threads/#thread-member-update) Gateway event. ### Path parameters | Field | Type | Description | | --- | --- | --- | | channel_id | snowflake | The ID of the thread | ### JSON body | Field | Type | Description | | --- | --- | --- | | flags?1 | integer | The notification [thread member flags](#thread-member-flags) | | muted? | boolean | Whether the thread is muted | | mute_config? | ?[guild mute configuration input](/http-api/users/settings/#guild-mute-configuration-input-object) object | The mute expiry of the thread, or null to clear it | 1 Replaces the three notification flags and keeps `HAS_INTERACTED`. A value of 0 clears them While `muted` is true, the member receives no push notification from the thread, including for a mention. A mute with an `end_time` stops when that time passes. ### Response | Status | Body | Condition | | --- | --- | --- | | 200 | [thread member](#thread-member-object) object | Settings changed | | 204 | empty | The body matched the stored settings | | 400 | [error response](/http-api/#error-response) | `flags` sets more than one notification flag or any other bit and the request returns `INVALID_THREAD_NOTIFICATION_SETTINGS` | | 400 | [error response](/http-api/#error-response) | Channel is not a thread and the request returns `INVALID_CHANNEL_TYPE` | | 403 | [error response](/http-api/#error-response) | Caller is a bot and the request returns `ACCESS_DENIED` | | 403 | [error response](/http-api/#error-response) | Caller cannot view the thread and the request returns `MISSING_ACCESS` | | 404 | [error response](/http-api/#error-response) | Caller is not a member and the request returns `UNKNOWN_THREAD_MEMBER` | ### Rate limit 10 requests per 10 seconds for each authenticated user and channel ID, on the `channel:thread:member:settings::channel_id` bucket.