Guild members¶
A guild member is an account that has joined a guild. The membership holds a nickname, roles, a guild profile and moderation state that apply in that guild only. Filtered member queries are on Guild member search and bans on Guild moderation.
All routes are relative to https://tebhos.com/api/v1, require authentication and accept both user sessions and bot tokens, except where a route is marked user-only (a valid bot token is then refused with 403 ACCESS_DENIED). A caller who is not a member of the guild receives 403 FORBIDDEN. A missing permission also returns 403 FORBIDDEN. Error bodies follow Errors.
Actions on another member follow the role hierarchy: the caller's highest role must rank strictly above the target's, the owner can act on anyone, and nobody can act on the owner.
Guild member object¶
Every /guilds/{guild_id}/members route on this page that returns a member returns this object: List guild members, Get current guild member, Get guild member, and a successful Modify current guild member or Modify guild member. The guild_member field of a user profile uses it as well.
Structure¶
| Field | Type | Description |
|---|---|---|
| user | partial user object | The account, with its real avatar hash, avatar_color and flags. bot is always present, false for a person |
| nick | ?string | The member's nickname in this guild, or null |
| avatar | ?string | The hash of the member's guild avatar, or null when they use their account avatar |
| banner | ?string | The hash of the member's guild banner, or null |
| accent_color | ?integer | The guild profile accent colour, or null |
| roles | array[snowflake] | The IDs of the member's roles. @everyone is never included |
| joined_at | ISO8601 timestamp | When the account joined the guild, with milliseconds and a Z suffix |
| mute | boolean | Whether a moderator has server-muted the member in voice |
| deaf | boolean | Whether a moderator has server-deafened the member in voice |
| communication_disabled_until | ?ISO8601 timestamp | When the member's communication timeout ends, or null. A past value means the timeout has expired |
| profile_flags | ?integer | Guild profile flags |
| mention_flags | ?integer | The member's reply-mention preference for this guild, or null to use the account setting |
REST responses do not include guild_id.
Example¶
{
"user": {
"id": "1489002177550843906",
"username": "ada",
"discriminator": "0000",
"global_name": "Ada",
"avatar": "5f2a9c",
"avatar_color": 3447003,
"flags": 0,
"bot": false
},
"nick": "Ada L.",
"avatar": null,
"banner": null,
"accent_color": null,
"roles": ["1489002177550843910"],
"joined_at": "2026-08-14T09:12:44.000Z",
"mute": false,
"deaf": false,
"communication_disabled_until": null,
"profile_flags": null,
"mention_flags": null
}
Gateway member object¶
The Ready payload and the Guild Member Add and Guild Member Update events carry the same guild member object. Events add guild_id to it.
TEBHOS member object¶
The older /servers/{guild_id}/members routes used by the web app (GET /servers/{guild_id}/members, GET /servers/{guild_id}/members/@me and GET /servers/{guild_id}/members/{user_id}) return this richer TEBHOS-specific object instead of the guild member object. It combines the standard member fields (user, roles, joined_at, mute, deaf) with flat convenience fields used by the TEBHOS apps. GET /servers/{guild_id}/members pages with offset (default 0) and limit (clamped to 1-200, default 100), orders members by join time, and returns the total member count in the X-Total-Count header.
Structure¶
| Field | Type | Description |
|---|---|---|
| user | member user object | The account the membership belongs to |
| roles | array[snowflake] | The IDs of the member's roles, highest position first. @everyone is never included |
| joined_at | ISO8601 timestamp | When the account joined the guild |
| nickname | ?string | The member's nickname in this guild |
| timeout_until | ?ISO8601 timestamp | When the member's communication timeout ends, or null. A past value means the timeout has expired |
| mute | boolean | Whether a moderator has server-muted the member in voice |
| deaf | boolean | Whether a moderator has server-deafened the member in voice |
| custom_roles | array[member role object] | The member's roles with their display data, highest position first |
| mention_flags | ?integer | The member's reply-mention preference for this guild, or null to use the account setting |
| avatar_url | ?string | An identifier of the member's guild-specific avatar, or null when they use their account avatar |
| id | snowflake | The user ID (same as user.id) |
| profile_id | snowflake | The user ID (same as user.id) |
| name | string | The account display name |
| username | ?string | The account username |
| image_url | string | The account avatar URL |
| bot | boolean | Whether the account is a bot |
| account_created_at | ?ISO8601 timestamp | When the account was created |
| invite_code | ?string | The invite code the member joined with, if recorded |
| custom_status | ?string | Always null in this response |
| active_frame_url | ?string | Always null in this response |
| active_badge_url | ?string | Always null |
| active_badge_name | ?string | Always null |
| inviter_name | ?string | Always null |
| inviter_image_url | ?string | Always null |
| role | string | Always an empty string. Kept for older clients |
Member user object¶
| Field | Type | Description |
|---|---|---|
| id | snowflake | The user ID |
| username | string | The username, or the display name when the account has no username |
| discriminator | string | Always "0" in this response |
| global_name | ?string | The display name |
| avatar | null | Always null in this response; use image_url |
| avatar_color | null | Always null in this response |
| flags | integer | Always 0 in this response |
| image_url | string | The avatar URL |
| bot? | boolean | Present and true only for a bot account |
| system? | boolean | Present and true only for a system account |
Member role object¶
| Field | Type | Description |
|---|---|---|
| id | snowflake | The role ID |
| name | string | The role name |
| color | string | The role colour as #RRGGBB |
| display_separately | boolean | The role's hoist value |
| position | integer | The role position |
Example¶
{
"user": {
"id": "1489002177550843906",
"username": "ada",
"discriminator": "0",
"global_name": "Ada",
"avatar": null,
"avatar_color": null,
"flags": 0,
"image_url": "https://tebhos.com/api/v1/avatars/1489002177550843906/5f2a9c.webp"
},
"roles": ["1489002177550843910"],
"joined_at": "2026-08-14T09:12:44+00:00",
"nickname": "Ada L.",
"timeout_until": null,
"mute": false,
"deaf": false,
"custom_roles": [
{"id": "1489002177550843910", "name": "Moderator", "color": "#3498DB", "display_separately": true, "position": 4}
],
"mention_flags": null,
"avatar_url": null,
"id": "1489002177550843906",
"profile_id": "1489002177550843906",
"name": "Ada",
"username": "ada",
"image_url": "https://tebhos.com/api/v1/avatars/1489002177550843906/5f2a9c.webp",
"bot": false,
"account_created_at": "2026-01-02T10:00:00+00:00",
"invite_code": "a1b2c3d4",
"custom_status": null,
"active_frame_url": null,
"active_badge_url": null,
"active_badge_name": null,
"inviter_name": null,
"inviter_image_url": null,
"role": ""
}
List guild members¶
GET /guilds/{guild_id}/members
Returns an array of up to limit guild member objects, ordered by ascending user ID. Requires membership; a caller who is not a member receives 403 MISSING_ACCESS. No permission bit is checked.
Rate limit: guild:members, 40 per 10 seconds per account and guild (shared with the other member reads, member search and List guild bans).
Query parameters¶
| Field | Type | Description |
|---|---|---|
| limit? | integer | The maximum number of members to return, 1-1000 (default 1) |
| after? | snowflake | Return only members whose user ID is higher than this user ID |
A limit outside 1-1000 or not an integer returns 400 INVALID_FORM_BODY with the field code INVALID_FORMAT on limit. An after that is not a snowflake also returns 400 INVALID_FORM_BODY. There is no offset parameter and no total count header.
To read every member, start without after, then repeat the request with after set to the user.id of the last member received until a page holds fewer than limit members.
curl "https://tebhos.com/api/v1/guilds/1489002177550843904/members?limit=1000&after=1489002177550843906" \
-H "Authorization: Bot $TEBHOS_BOT_TOKEN"
Get current guild member¶
GET /guilds/{guild_id}/members/@me
Returns the caller's own guild member object. Requires membership; a caller who is not a member receives 403 MISSING_ACCESS.
Rate limit: guild:members, 40 per 10 seconds per account and guild.
Get guild member¶
GET /guilds/{guild_id}/members/{user_id}
Returns one member's guild member object. Requires membership; a caller who is not a member receives 403 MISSING_ACCESS. A user who is not a member returns 404 UNKNOWN_MEMBER.
Rate limit: guild:members, 40 per 10 seconds per account and guild.
Modify current guild member¶
PATCH /guilds/{guild_id}/members/@me
Updates the caller's own nickname and guild profile. Requires membership. Every member of the guild receives Guild Member Update.
Rate limit: guild:member:update, 20 per 10 seconds per account and guild.
JSON body¶
Every field is optional; an omitted field is left unchanged.
| Field | Type | Description |
|---|---|---|
| nick? | ?string | The nickname, at most 32 characters after trimming. null or an empty string removes it |
| nickname? | string | Same as nick; takes precedence when both are sent. An empty string removes the nickname |
| bio? | string | Guild profile biography, at most 4000 characters. An empty string removes it |
| pronouns? | string | Guild pronouns, at most 40 characters. An empty string removes them |
| accent_color? | integer | Guild profile accent colour as an RGB integer |
| accent_clear? | boolean | true removes the guild accent colour |
| avatar_unset? | boolean | true removes the guild avatar |
| banner_unset? | boolean | true hides the banner for this guild |
| mention_flags? | integer | The reply-mention preference for this guild |
- Changing the nickname needs
CHANGE_NICKNAME. Without it the nickname change is silently skipped and the other fields are still applied. A member who is timed out and tries to change the nickname receives 403FORBIDDEN. bio,pronouns,accent_color,accent_clear,avatar_unsetandbanner_unsetare guild profile features and need TEBHOS Pro; without it the whole request fails with 403FORBIDDEN.bio,pronounsand the accent colour can each change at most 25 times per 30 minutes per member and guild. A change that exceeds this fails with 400INVALID_FORM_BODYand a field code ofBIO_CHANGED_TOO_MANY_TIMES,PRONOUNS_CHANGED_TOO_MANY_TIMESorACCENT_COLOR_CHANGED_TOO_MANY_TIMES. Sending the current value does not count.
A successful request returns 200 with the caller's updated guild member object.
curl -X PATCH https://tebhos.com/api/v1/guilds/1489002177550843904/members/@me \
-H "Authorization: Bot $TEBHOS_BOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"nick": "Build Bot"}'
Guild avatar and banner¶
A guild-specific avatar or banner image is uploaded in two steps. Both need TEBHOS Pro and are user-only:
- Request an upload URL for the account avatar or banner, as described in Change avatar and Change banner, and upload the image.
- Instead of confirming it for the account, confirm it for the guild with
POST /servers/{guild_id}/members/@me/avatar/confirmorPOST /servers/{guild_id}/members/@me/banner/confirmand the body{"storage_key": string}.
The guild avatar and the guild banner can each change at most 25 times per 30 minutes per member and guild (field codes AVATAR_CHANGED_TOO_MANY_TIMES and BANNER_CHANGED_TOO_MANY_TIMES).
Modify guild member¶
PATCH /guilds/{guild_id}/members/{user_id}
Applies one moderation change to a member. Every successful change returns 200 with the member's updated guild member object and dispatches Guild Member Update with the full member.
Rate limit: guild:member:update, 20 per 10 seconds per client and guild.
JSON body¶
| Field | Type | Description |
|---|---|---|
| mute? | boolean | Server-mute or unmute the member in voice |
| deaf? | boolean | Server-deafen or undeafen the member in voice |
| channel_id? | ?snowflake | Move the member to this voice channel, or null to disconnect them from voice |
| connection_id? | string | Apply the move or disconnect to this one voice connection only (default: every connection) |
| roles? | array[snowflake] | The member's complete new role set |
| nick? | ?string | The member's nickname, at most 32 characters. null or an empty string removes it |
| nickname? | ?string | Same as nick |
| communication_disabled_until? | ?ISO8601 timestamp | When the member's timeout ends, or null to remove the timeout |
| timeout_reason? | string | The reason recorded in the audit log with a new timeout |
One kind of change per request
TEBHOS applies only one group of fields per request, in this order of precedence: voice (mute, deaf, channel_id), then roles, then the nickname, then communication_disabled_until. Fields from a lower group in the same request are ignored. Send separate requests to change several things. A body with none of these fields returns 400 BAD_REQUEST.
Voice moderation (mute, deaf, channel_id). mute and deaf both need MUTE_MEMBERS; channel_id needs MOVE_MEMBERS. Acting on another member also needs a higher rank. The member must be connected to voice in the guild.
| Status | Code | Condition |
|---|---|---|
| 400 | USER_NOT_IN_VOICE |
The member is not in a voice channel, or connection_id is not one of their connections |
| 400 | INVALID_FORM_BODY |
The destination does not exist (errors[0].code CHANNEL_DOES_NOT_EXIST) or is not a voice channel (CHANNEL_MUST_BE_VOICE) |
| 403 | MISSING_PERMISSIONS |
The caller or the member lacks CONNECT in the destination |
| 404 | UNKNOWN_MEMBER |
The user is not a member |
A move records a MEMBER_MOVE audit entry, a disconnect MEMBER_DISCONNECT, and a mute or deafen change MEMBER_UPDATE.
Roles (roles). Replaces the member's role set. The guild owner can set any roles. Anyone else needs MANAGE_ROLES and must outrank every role that is added or removed; the target's own rank is not checked. IDs that are not roles of this guild are dropped. Including the @everyone role returns 400 BAD_REQUEST. Giving roles to a member who joined through a temporary invite makes the membership permanent. No audit entry is recorded.
Nickname (nick or nickname). Changing another member's nickname needs MANAGE_NICKNAMES and a higher rank. When user_id is the caller, the request follows Modify current guild member instead.
Timeout (communication_disabled_until). Needs MODERATE_MEMBERS and a higher rank, and is refused with 403 FORBIDDEN when the target is the caller or holds ADMINISTRATOR. A time in the past removes the timeout, and a time more than 365 days ahead returns 400 INVALID_FORM_BODY. A value that is not an RFC 3339 timestamp returns 400 BAD_REQUEST. Setting a timeout records an audit entry (see MEMBER_TIMEOUT). While the timeout lasts, the member cannot communicate in the guild; see Communication timeout.
A target who is not a member returns 404 NOT_FOUND for the roles, nickname and timeout groups.
curl -X PATCH https://tebhos.com/api/v1/guilds/1489002177550843904/members/1489002177550843906 \
-H "Authorization: Bot $TEBHOS_BOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"communication_disabled_until": "2026-09-24T12:00:00Z", "timeout_reason": "Spam"}'
Older timeout and nickname routes
The web app also uses POST /servers/{guild_id}/members/{user_id}/timeout with {"timeout_until": ?string, "reason"?: string}, DELETE /servers/{guild_id}/members/{user_id}/timeout, and PATCH /servers/{guild_id}/members/{user_id}/nickname with {"nickname": string}. They follow the same rules as the fields above.
Remove guild member¶
DELETE /guilds/{guild_id}/members/{user_id}
Kicks a member from the guild. Requires KICK_MEMBERS and a higher rank than the target. Returns 200 with {"message": string}.
Rate limit: guild:member:remove, 20 per 10 seconds per account and guild.
The caller, the guild owner and a user who is not a member all return 404 NOT_FOUND.
The remaining members receive Guild Member Remove and the removed account's sessions receive Guild Delete. The guild is removed from the account's guild folders, and a MEMBER_KICK audit log entry is recorded. The removed member loses their nickname, roles and guild profile; they can rejoin with an invite.
Transfer guild ownership¶
POST /guilds/{guild_id}/transfer-ownership
Makes another member the guild owner and returns the updated guild object. User-only. Only the current owner can call it. The guild receives Guild Update.
Rate limit: guild:update, 20 per 10 seconds per client and guild.
JSON body¶
| Field | Type | Description |
|---|---|---|
| new_owner_id | snowflake | The member who becomes the owner |
No password or sudo proof is needed. Only owner_id changes: the previous owner keeps their membership and roles. If the guild has a Business Class subscription, its perks move to the new owner.
| Status | Code | Condition |
|---|---|---|
| 400 | BAD_REQUEST |
new_owner_id is missing or not a snowflake, is the caller, or is not a member of the guild |
| 403 | FORBIDDEN |
The caller is not the owner |
curl -X POST https://tebhos.com/api/v1/guilds/1489002177550843904/transfer-ownership \
-H "Authorization: Bearer $TEBHOS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"new_owner_id": "1489002177550843906"}'
Add guild member role¶
PUT /guilds/{guild_id}/members/{user_id}/roles/{role_id}
Adds one role to a member. Returns 200 with {"message": string}. The guild receives Guild Member Update.
Rate limit: guild:member:role:add, 20 per 10 seconds per client and guild.
- The guild owner can add any role of the guild; a role that does not exist returns 404
NOT_FOUND. - Anyone else needs
MANAGE_ROLESand a rank above the role; a role that does not exist returns 403FORBIDDEN. - The
@everyonerole returns 400BAD_REQUEST. - A user who is not a member returns 404
NOT_FOUND.
Adding a role the member already has succeeds without change. No audit entry is recorded.
Remove guild member role¶
DELETE /guilds/{guild_id}/members/{user_id}/roles/{role_id}
Removes one role from a member. Returns 200 with {"message": string}. The same rules as Add guild member role apply, and the guild receives Guild Member Update.
Rate limit: guild:member:role:remove, 20 per 10 seconds per account and guild.