Users¶
A user is a TEBHOS account. Other accounts see the partial user object, and the owner sees the user object. Changes to your own account are covered on Current user.
All paths on this page are relative to https://tebhos.com/api/v1.
| Object | Purpose |
|---|---|
| Partial user | Public account representation embedded in messages, members, relationships and so on |
| User | Private representation returned to the account owner |
| User settings | Account-wide settings record |
| User profile | Full profile with privacy applied, returned by Get user profile |
| Profile | TEBHOS profile record returned by Get profile |
| Profile card | Profile record with mutuals and per-guild data, returned by Get user profile card |
Authentication on user routes¶
| Credential | Accepted |
|---|---|
User session (Authorization: Bearer <token>) |
Every route on the user pages |
Bot token (Authorization: Bot <token>) |
Only where a route says so. Everywhere else a valid bot token is rejected with 403 ACCESS_DENIED |
| OAuth2 access token | Only Get current user, with the identify scope. Everywhere else a valid access token is rejected with 403 ACCESS_DENIED |
See Authentication for how tokens are obtained.
Partial user object¶
The public account representation. It is what Get user returns and what other resources embed as author, user, and similar fields.
Structure¶
| Field | Type | Description |
|---|---|---|
| id | snowflake | The snowflake that identifies the account |
| username | string | The account username. TEBHOS usernames are unique on their own |
| discriminator | string | Legacy tag suffix. Human accounts always have discriminator 0, see the note below |
| global_name | ?string | The display name, or null when none is set |
| avatar | ?string | The image hash of the avatar, or null when none is set |
| avatar_color | ?integer | Packed 24-bit RGB colour derived from the avatar, or null |
| bot? | boolean | true for a bot account, omitted otherwise |
| system? | boolean | true for a TEBHOS system account, omitted otherwise |
| flags | integer | Public user flags |
| mention_flags? | integer | Reply mention preference, omitted when the account has no preference |
Discriminators
TEBHOS usernames are globally unique, so human accounts do not use a four-digit tag. Their stored discriminator is 0: partial user objects serialise it as "0", and the private user object as "0000". Bot accounts receive a generated numeric discriminator when the application is created.
Example¶
{
"id": "1501314428688998182",
"username": "aria",
"discriminator": "0",
"global_name": "Aria",
"avatar": "a_2f1c9d7be4a350c8e0f1",
"avatar_color": 5793266,
"flags": 0
}
Deleted and system accounts¶
An account whose deletion has completed is serialised with username DeletedUser, discriminator 0000, global name Deleted User, null avatar and avatar_color, and flags of 0 in the user object and in embedded author objects built by the API. An account that is only scheduled for deletion keeps its normal representation during the grace period.
The built-in system account has ID 0, username TEBHOS, discriminator 0000, bot and system set to true, and the STAFF flag. It sends TEBHOS system messages.
Image hashes¶
avatar and banner hold a content hash, not a URL. A hash that starts with a_ belongs to an animated image. Build the URL from the hash:
https://tebhos.com/api/v1/avatars/{user_id}/{avatar_hash}.webp
https://tebhos.com/api/v1/banners/{user_id}/{banner_hash}.webp
See Media proxy routes for sizes and formats. An account without an avatar has avatar: null; clients render a default avatar derived from the user ID.
Animated avatars and every profile banner are TEBHOS Pro features. In the user object the a_ prefix is removed from the avatar hash, and banner is null, while the account has no active premium (bots are always entitled).
Public user flags¶
flags holds the publicly visible subset of the account's stored flags. STAFF is removed while the account also has the hidden-staff flag.
| Value | Name | Description |
|---|---|---|
| 1 << 0 | STAFF | Account is a TEBHOS staff member |
| 1 << 1 | CTP_MEMBER | Reserved legacy program flag; TEBHOS does not assign it |
| 1 << 2 | PARTNER | Account is a partner |
| 1 << 3 | BUG_HUNTER | Account is a bug hunter |
| 1 << 4 | FRIENDLY_BOT | Bot accepts friend requests from users |
| 1 << 5 | FRIENDLY_BOT_MANUAL_APPROVAL | Bot requires manual approval for friend requests |
| 1 << 6 | SPAMMER | Account is flagged as a spammer |
Note
Get user is served by the TEBHOS user service, which masks only the hidden-staff flag, so its flags value can carry other low-order stored bits. Test for the bits above and ignore the rest.
Reply mention preferences¶
The account-wide default applied when someone replies to one of this account's messages. mention_flags is one of the values below and is omitted from a serialised user while the stored value is 0. Set it with Modify current user.
| Value | Name | Description |
|---|---|---|
| 0 | NO_PREFERENCE | The sender chooses whether each reply mentions this account |
| 1 | PREFER_MENTION | Replies mention this account by default |
| 2 | PREFER_NO_MENTION | Replies omit the mention by default |
User object¶
The private representation of the current account, returned by Get current user and by the operations that change the account. It extends the partial user object.
Structure¶
| Field | Type | Description |
|---|---|---|
| id | snowflake | The account ID |
| username | string | The account username |
| discriminator | string | Four-digit discriminator; "0000" for human accounts |
| global_name | ?string | The display name, or null |
| avatar | ?string | Image hash of the avatar, or null. The a_ prefix is removed without an active premium entitlement |
| avatar_color | ?integer | Packed 24-bit RGB colour derived from the avatar, or null |
| bot? | boolean | true for a bot account, omitted otherwise |
| system? | boolean | true for a system account, omitted otherwise |
| flags | integer | Public user flags |
| mention_flags? | integer | Reply mention preference, omitted when 0 |
| is_staff | boolean | Whether the account has the staff flag, even when it is hidden from flags |
| acls | array[string] | Administrative access entries held by the account; empty for ordinary accounts |
| traits | array[string] | Account traits in sorted order. premium is present exactly when premium entitlements are active |
| ?string | The account email address, or null | |
| email_bounced | boolean | Whether mail to the current address bounced |
| phone | ?string | Always null |
| has_verified_phone | boolean | Whether a phone number was verified |
| bio | ?string | The profile biography, or null |
| pronouns | ?string | The profile pronouns, or null |
| accent_color | ?integer | The profile accent colour as packed 24-bit RGB, or null |
| timezone | ?string | The IANA timezone identifier shown on the profile, or null |
| timezone_privacy_flags | integer | Profile field privacy flags for the timezone |
| banner | ?string | Image hash of the profile banner, or null when none is set or the account has no premium entitlement |
| banner_color | ?integer | Packed 24-bit RGB colour derived from the banner, or null |
| mfa_enabled | boolean | Whether an authenticator is configured |
| authenticator_types? | array[integer] | Authenticator types configured for the account; omitted when there are none |
| verified | boolean | Whether the email address is verified |
| premium_type | integer | Premium type; 0 while premium entitlements are not active |
| premium_since | ?ISO8601 timestamp | When premium was first activated; null while premium is not active |
| premium_until | ?ISO8601 timestamp | End of current premium access (the later of the subscription end and any gift extension), or null |
| premium_will_cancel | boolean | Whether the subscription ends at the next billing boundary |
| premium_billing_cycle | ?string | The premium billing cycle, or null |
| premium_lifetime_sequence | ?integer | The lifetime premium sequence number, or null |
| premium_grace_ends_at | ?ISO8601 timestamp | End of the post-expiry grace interval, or null |
| premium_discriminator | boolean | Whether the discriminator was chosen under a premium entitlement |
| premium_badge_hidden | boolean | Whether the premium badge is hidden from the public profile |
| premium_badge_masked | boolean | Whether a lifetime badge is shown as a subscription badge |
| premium_badge_timestamp_hidden | boolean | Whether the premium start date is hidden from the public profile |
| premium_badge_sequence_hidden | boolean | Whether the lifetime sequence is hidden from the public profile |
| premium_purchase_disabled | boolean | Whether premium purchases are disabled for the account |
| premium_enabled_override | boolean | Whether a staff override grants premium entitlements |
| premium_perks_disabled | boolean | Whether premium entitlements are suspended for the account |
| password_last_changed_at | ?ISO8601 timestamp | Time of the most recent password change, or null |
| last_voice_activity_sharing_change_at | ?ISO8601 timestamp | Time of the last voice activity sharing change, or null. Drives its 24-hour cooldown |
| required_actions | array[string] | Always an empty array on TEBHOS |
| nsfw_allowed | boolean | Compatibility field. TEBHOS has no age-restricted content; ignore it |
| has_dismissed_premium_onboarding | boolean | Whether premium onboarding was dismissed; false while premium is not active |
| has_ever_purchased | boolean | Whether the account has completed a purchase |
| has_unread_gift_inventory | boolean | Whether the gift inventory has unread items |
| unread_gift_inventory_count | integer | Number of unread gift inventory items |
| pending_bulk_message_deletion | ?pending bulk message deletion object | The scheduled deletion of every message the account sent, or null |
| terms_agreed_at | ?ISO8601 timestamp | Time of the most recent terms of service acceptance, or null |
| privacy_agreed_at | ?ISO8601 timestamp | Time of the most recent privacy policy acceptance, or null |
Premium state is computed as follows: an account is premium when it is a bot, when a staff override is set, or when it has a paid premium type whose premium_until has not passed. After premium_until, entitlements stay active until premium_grace_ends_at, or for 3 days when that value is null. premium_perks_disabled switches entitlements off regardless.
Required actions
The field exists for compatibility. TEBHOS does not currently place accounts into a restricted required-action state, so the array is always empty.
Example¶
{
"id": "1501314428688998182",
"username": "aria",
"discriminator": "0000",
"global_name": "Aria",
"avatar": "2f1c9d7be4a350c8e0f1",
"avatar_color": 5793266,
"flags": 0,
"is_staff": false,
"acls": [],
"traits": [],
"email": "[email protected]",
"email_bounced": false,
"phone": null,
"has_verified_phone": false,
"bio": "Hello!",
"pronouns": null,
"accent_color": null,
"timezone": "Europe/Istanbul",
"timezone_privacy_flags": 1,
"banner": null,
"banner_color": null,
"mfa_enabled": true,
"authenticator_types": [0],
"verified": true,
"premium_type": 0,
"premium_since": null,
"premium_until": null,
"premium_will_cancel": false,
"premium_billing_cycle": null,
"premium_lifetime_sequence": null,
"premium_grace_ends_at": null,
"premium_discriminator": false,
"premium_badge_hidden": false,
"premium_badge_masked": false,
"premium_badge_timestamp_hidden": false,
"premium_badge_sequence_hidden": false,
"premium_purchase_disabled": false,
"premium_enabled_override": false,
"premium_perks_disabled": false,
"password_last_changed_at": "2026-08-01T10:15:00.000Z",
"last_voice_activity_sharing_change_at": null,
"required_actions": [],
"nsfw_allowed": false,
"has_dismissed_premium_onboarding": false,
"has_ever_purchased": false,
"has_unread_gift_inventory": false,
"unread_gift_inventory_count": 0,
"terms_agreed_at": "2026-07-20T08:00:00.000Z",
"privacy_agreed_at": "2026-07-20T08:00:00.000Z",
"pending_bulk_message_deletion": null
}
Pending bulk message deletion object¶
Present while a deletion of every message the account has sent is scheduled (see Content).
| Field | Type | Description |
|---|---|---|
| scheduled_at | ISO8601 timestamp | When the deletion runs |
| channel_count | integer | Number of channels holding a message that will be deleted |
| message_count | integer | Number of messages that will be deleted |
The counts are computed when the deletion is scheduled.
Authenticator types¶
| Value | Name | Description |
|---|---|---|
| 0 | TOTP | Time-based one-time password authenticator app |
| 2 | WEBAUTHN | WebAuthn second factor |
authenticator_types only ever contains these two values. Registering a passkey does not add WEBAUTHN on TEBHOS, so today the array reports only TOTP, and mfa_enabled reflects TOTP only. Passkeys still count as a second factor for sudo verification. See MFA.
Premium types¶
| Value | Name | Description |
|---|---|---|
| 0 | NONE | No premium |
| 1 | SUBSCRIPTION | Monthly or yearly TEBHOS Pro subscription |
| 2 | LIFETIME | Lifetime TEBHOS Pro |
See Premium for purchasing, which TEBHOS handles through Polar.
Profile field privacy flags¶
Controls who can see an individual profile field (the timezone and each connection). A value of 0 hides the field from everyone, including the owner's own profile card.
| Value | Name | Description |
|---|---|---|
| 1 << 0 | EVERYONE | Anyone who can see the full profile |
| 1 << 1 | FRIENDS | Friends |
| 1 << 2 | MUTUAL_GUILDS | Members of a guild shared with the account |
User settings object¶
The complete account-wide settings record. Get current user settings and Modify current user settings return it, and the USER_SETTINGS_UPDATE Gateway event carries it. Every field below is always present. A field that was never written is returned with its initial value.
Structure¶
| Field | Type | Description |
|---|---|---|
| status | string | Presence status |
| status_resets_at | ?ISO8601 timestamp | When the client should reset status, or null |
| status_resets_to | ?string | Presence status applied at status_resets_at, or null |
| theme | string | Theme value |
| locale | ?string | The interface locale, or null when none was chosen |
| restricted_guilds | array[snowflake] | Guilds where direct messages from members are restricted, in ascending ID order |
| bot_restricted_guilds | array[snowflake] | Guilds where direct messages from bots are restricted |
| default_guilds_restricted | boolean | Whether newly joined guilds are added to restricted_guilds |
| bot_default_guilds_restricted | boolean | Whether newly joined guilds are added to bot_restricted_guilds |
| inline_attachment_media | boolean | Whether attachment media is shown inline |
| inline_embed_media | boolean | Whether embed media is shown inline |
| gif_auto_play | boolean | Whether GIFs play automatically |
| render_embeds | boolean | Whether embeds are rendered |
| render_reactions | boolean | Whether reactions are rendered |
| animate_emoji | boolean | Whether custom emoji animate |
| animate_stickers | integer | Sticker animation setting |
| render_spoilers | integer | Spoiler rendering setting |
| message_display_compact | boolean | Whether messages use compact display |
| friend_source_flags | integer | Friend source flags |
| incoming_call_flags | integer | Incoming call flags |
| group_dm_add_permission_flags | integer | Group DM add permission flags |
| guild_positions | array[snowflake] | Legacy guild ordering, kept for compatibility |
| guild_folders | array[guild folder object] | The guild sidebar layout |
| custom_status | ?custom status object | The current custom status, or null |
| afk_timeout | integer | Idle seconds before the account is presented as away |
| time_format | integer | Time format setting |
| developer_mode | boolean | Whether developer mode (copy ID menus and similar) is enabled |
| explicit_content_filter | integer | Legacy media filter value kept for older clients (0-2) |
| trusted_domains | array[string] | External link domains the account trusts. The single entry * trusts every domain |
| default_hide_muted_channels | boolean | Whether newly joined guilds hide muted channels |
| sensitive_content_friend_dm_filter | integer | Sensitive media filter for DMs with friends |
| sensitive_content_non_friend_dm_filter | integer | Sensitive media filter for DMs with non-friends |
| sensitive_content_guild_filter | integer | Sensitive media filter in guilds |
| synced_preferences | string | Base64-encoded synced preferences snapshot; the empty string when nothing is stored |
| profile_privacy | integer | Profile privacy level |
| default_share_voice_activity | boolean | Whether new friendships start with voice activity sharing on. Read-only here; see Modify voice activity sharing |
| suppress_unprivileged_self_mentions | boolean | Staff-only mention suppression switch; always false for other accounts |
| suppress_unprivileged_self_mentions_bypass_user_ids | array[snowflake] | Staff-only; users exempt from mention suppression |
| staff_dm_access_user_ids | array[snowflake] | Staff-only; users granted staff DM access |
Custom status object¶
The text and emoji shown under the account's name. It is stored with the profile, so Modify current user settings and the custom-status fields of Modify current user write the same value.
| Field | Type | Description |
|---|---|---|
| text | ?string | The status text (up to 128 characters), or null |
| emoji_id | ?snowflake | The custom emoji shown beside the text, or null |
| emoji_name | ?string | The Unicode emoji shown beside the text, or null. Null when emoji_id is set |
| emoji_animated | boolean | Always false; resolve the emoji to find out whether it is animated |
| expires_at | ?ISO8601 timestamp | When the status expires, or null for no expiry |
An expired status is returned as null.
{
"text": "shipping",
"emoji_id": null,
"emoji_name": "🚀",
"emoji_animated": false,
"expires_at": "2026-09-24T18:00:00+00:00"
}
Guild folder object¶
One entry of the guild sidebar layout.
| Field | Type | Description |
|---|---|---|
| id | integer | Folder identifier. -1 is the uncategorised folder, which holds guilds that are not in a named folder |
| name | ?string | Folder name, or null |
| color | ?integer | Folder colour as packed 24-bit RGB |
| flags | integer | Guild folder flags |
| icon | string | Guild folder icon |
| guild_ids | array[snowflake] | Guild IDs in the folder, in sidebar order |
Leaving or being removed from a guild removes its ID from every folder and drops every non-uncategorised folder that becomes empty. Joining a guild does not change the layout.
{
"id": -1,
"name": null,
"color": 0,
"flags": 0,
"icon": "folder",
"guild_ids": ["1501314428688998182", "1501314428688998183"]
}
Guild folder flags¶
| Value | Name | Description |
|---|---|---|
| 1 << 0 | SHOW_ICON_WHEN_COLLAPSED | Show the folder icon instead of guild previews while collapsed |
Guild folder icons¶
| Value | Description |
|---|---|
| folder | Folder icon, used when no icon is supplied |
| star | Star icon |
| heart | Heart icon |
| bookmark | Bookmark icon |
| game_controller | Game controller icon |
| shield | Shield icon |
| music_note | Music note icon |
Sticker animation settings¶
| Value | Name | Description |
|---|---|---|
| 0 | ALWAYS_ANIMATE | Always animate stickers |
| 1 | ANIMATE_ON_INTERACTION | Animate stickers on hover or interaction |
| 2 | NEVER_ANIMATE | Never animate stickers |
Spoiler rendering settings¶
| Value | Name | Description |
|---|---|---|
| 0 | ALWAYS | Always reveal spoilers |
| 1 | ON_CLICK | Reveal spoilers on click |
| 2 | IF_MODERATOR | Reveal spoilers for moderators |
Time format settings¶
| Value | Name | Description |
|---|---|---|
| 0 | AUTO | Pick the time format from the locale |
| 1 | TWELVE_HOUR | 12-hour clock |
| 2 | TWENTY_FOUR_HOUR | 24-hour clock |
Sensitive media filters¶
| Value | Name | Description |
|---|---|---|
| 0 | SHOW | Show sensitive media |
| 1 | BLUR | Blur sensitive media until revealed |
| 2 | BLOCK | Hide sensitive media |
All three values are accepted for every filter field, including sensitive_content_guild_filter.
Profile privacy levels¶
Controls who sees the full profile. Friends always see it, and so does the account itself; bot profiles are never restricted.
| Value | Name | Description |
|---|---|---|
| 0 | ALL_GUILDS | Friends and members of any shared guild see the full profile |
| 1 | SMALL_GUILDS_ONLY | Friends and members of a shared guild with at most 200 members see the full profile |
| 2 | FRIENDS_ONLY | Only friends see the full profile |
A restricted viewer still receives the profile, but with bio, pronouns, the premium badge, timezone_offset and connected_accounts removed and profile_limited: true. See Get user profile and Get user profile card. Get profile removes bio and pronouns for a restricted viewer.
Friend source flags¶
Who may send the account a friend request.
| Value | Name | Description |
|---|---|---|
| 1 << 0 | MUTUAL_FRIENDS | Users who share a friend with the account |
| 1 << 1 | MUTUAL_GUILDS | Users who share a guild with the account |
| 1 << 2 | NO_RELATION | Anyone |
Incoming call flags¶
Who may start a DM call with the account. SILENT_EVERYONE makes permitted calls arrive without ringing.
| Value | Name | Description |
|---|---|---|
| 1 << 0 | FRIENDS_OF_FRIENDS | Friends of friends |
| 1 << 1 | GUILD_MEMBERS | Members of a shared guild |
| 1 << 2 | EVERYONE | Everyone |
| 1 << 3 | FRIENDS_ONLY | Only friends |
| 1 << 4 | NOBODY | Nobody |
| 1 << 5 | SILENT_EVERYONE | Permitted calls arrive silently |
When stored, a value containing FRIENDS_ONLY becomes FRIENDS_ONLY alone, and otherwise a value containing NOBODY becomes NOBODY alone; SILENT_EVERYONE is kept in both cases.
Group DM add permission flags¶
Who may add the account to a group DM.
| Value | Name | Description |
|---|---|---|
| 1 << 0 | FRIENDS_OF_FRIENDS | Friends of friends |
| 1 << 1 | GUILD_MEMBERS | Members of a shared guild |
| 1 << 2 | EVERYONE | Everyone |
| 1 << 3 | FRIENDS_ONLY | Only friends |
| 1 << 4 | NOBODY | Nobody |
When stored, FRIENDS_ONLY wins over NOBODY, which wins over EVERYONE; the winning flag is stored alone.
User profile object¶
The record returned by Get user profile.
| Field | Type | Description |
|---|---|---|
| user | partial user object | The account. Its flags carry the public badges |
| user_profile | object | {bio, pronouns, banner, banner_color, accent_color}. bio and pronouns are null when the profile is restricted; banner is null without premium entitlement |
| guild_member? | guild member object | The target's membership in guild_id; present only when both you and the target are members |
| guild_member_profile? | object | {bio, pronouns, banner, accent_color} of the target's per-guild profile; present with guild_member |
| premium_type? | integer | Premium type shown as a badge. Omitted when restricted, hidden by the owner, or expired. A lifetime badge masked by the owner shows as a subscription |
| premium_since? | ISO8601 timestamp | Premium start, unless hidden by the owner |
| premium_lifetime_sequence? | integer | Lifetime sequence number, unless hidden by the owner |
| mutual_friends? | array[partial user object] | With with_mutual_friends=true and another account: shared friends, newest account first |
| mutual_guilds? | array[object] | With with_mutual_guilds=true and another account: {id, nick} for each shared guild, nick being the target's nickname there |
| connected_accounts | array[profile connection object] | Verified connections whose privacy flags admit you, in the owner's order; empty when restricted |
| timezone_offset | ?integer | The target's current UTC offset in minutes, or null when unset, hidden by its privacy flags, or restricted |
| profile_limited? | boolean | true when profile privacy restricted the profile; omitted otherwise |
Profile object¶
The profile record returned by Get profile. It combines core account fields with TEBHOS profile customisation.
| Field | Type | Description |
|---|---|---|
| id | snowflake | The account ID |
| name | string | The display name, or the empty string when none is set |
| username | ?string | The username |
| string | The email address when you read your own profile; the empty string otherwise | |
| image_url | string | Resolved avatar URL, or the empty string. Prefer avatar_hash |
| avatar_hash | ?string | Image hash of the avatar |
| bio | ?string | Biography |
| custom_status | ?string | Custom status text; null when unset or expired |
| custom_status_emoji_id | ?string | Custom status emoji: a custom emoji ID or a Unicode emoji |
| custom_status_expires_at | ?ISO8601 timestamp | Custom status expiry |
| banner_color | ?string | Profile banner colour as #RRGGBB |
| banner_type | ?string | Banner display type, for example color or image |
| banner_image_url | ?string | Resolved banner image URL |
| banner_hash | ?string | Image hash of the banner |
| active_frame_url | ?string | Avatar frame selected by the account |
| active_badge_url | ?string | Premium badge image selected by the account |
| active_badge_name | ?string | Premium badge name |
| boost_badge_url | ?string | Booster badge image selected by the account |
| boost_badge_name | ?string | Booster badge name |
| role | string | Platform role, user for ordinary accounts |
| created_at | ISO8601 timestamp | Account creation time, derived from the snowflake |
| pronouns | ?string | Pronouns |
| accent_color | ?integer | Accent colour as packed 24-bit RGB |
| bot | boolean | Whether the account is a bot |
| system | boolean | Whether the account is a system account |
Profile card object¶
The richer record returned by Get user profile card. When the request names a guild, top-level image_url, bio, pronouns, accent_color and banner fields hold the member's effective values (their per-guild profile overrides the global one).
| Field | Type | Description |
|---|---|---|
| id | snowflake | The account ID |
| name | string | The display name, or the empty string |
| username | ?string | The username |
| image_url | string | Effective avatar URL |
| avatar_hash | ?string | Global avatar hash; null when a per-guild avatar overrides it |
| bio | ?string | Effective biography; null on a restricted card |
| pronouns | ?string | Effective pronouns; null on a restricted card |
| accent_color | ?integer | Effective accent colour |
| custom_status | ?string | Custom status text |
| custom_status_emoji_id | ?string | Custom status emoji |
| custom_status_expires_at | ?ISO8601 timestamp | Custom status expiry |
| banner_color | ?string | Banner colour as #RRGGBB |
| banner_type | ?string | Effective banner type |
| banner_image_url | ?string | Effective banner image URL |
| banner_hash | ?string | Global banner hash; null when a per-guild banner overrides it |
| active_frame_url | ?string | Selected avatar frame |
| active_badge_url | ?string | Selected premium badge image |
| active_badge_name | ?string | Selected premium badge name |
| boost_badge_url | ?string | Selected booster badge image |
| boost_badge_name | ?string | Selected booster badge name |
| premium_since | ?ISO8601 timestamp | When premium started; null on a restricted card |
| boost_since | ?ISO8601 timestamp | Start of the account's oldest active guild boost, or null |
| mutual_servers | array[mutual server object] | Guilds you share with the account |
| mutual_friends | integer | Number of mutual friends |
| mutual_friends_list | array[mutual friend object] | Mutual friends, sorted by name |
| friend_status | ?string | Your relationship with the account: ACCEPTED, BLOCKED, PENDING (either direction), or null |
| note | ?string | Your private note about the account |
| nickname | ?string | Your private nickname for the account |
| is_self | boolean | Whether the card is your own |
| member_id | ?snowflake | The account ID when server_id was given and the account is a member of that guild, otherwise null |
| roles | array[role summary object] | The member's roles in that guild, highest first; empty without server_id |
| joined_at | ?ISO8601 timestamp | When the account joined that guild, or null |
| member_profile | ?member profile object | The member's raw per-guild profile, or null |
| created_at | ISO8601 timestamp | Account creation time |
| bot | boolean | Whether the account is a bot |
| system | boolean | Whether the account is a system account |
| timezone_offset | ?integer | The account's current UTC offset in minutes, or null when unset or not visible to you |
| connected_accounts | array[profile connection object] | Verified connections whose privacy flags admit you, in the owner's order |
| profile_limited? | boolean | true when profile privacy restricted this card; omitted otherwise |
Mutual server object¶
| Field | Type | Description |
|---|---|---|
| id | snowflake | Guild ID |
| name | string | Guild name |
| image_url | string | Guild icon URL, or the empty string |
Mutual friend object¶
| Field | Type | Description |
|---|---|---|
| id | snowflake | User ID |
| name | string | Display name, falling back to the username |
| username | ?string | Username |
| image_url | string | Avatar URL, or the empty string |
Role summary object¶
| Field | Type | Description |
|---|---|---|
| id | snowflake | Role ID |
| name | string | Role name |
| color | string | Role colour as #RRGGBB |
Member profile object¶
| Field | Type | Description |
|---|---|---|
| nickname | ?string | Guild nickname |
| avatar_url | ?string | Per-guild avatar hash, or null to inherit |
| banner_url | ?string | Per-guild banner hash; the empty string means the banner is turned off, null inherits |
| bio | ?string | Per-guild biography; null on a restricted card |
| pronouns | ?string | Per-guild pronouns; null on a restricted card |
| accent_color | ?integer | Per-guild accent colour |
Profile connection object¶
| Field | Type | Description |
|---|---|---|
| id | string | Connection ID |
| type | string | Connection provider |
| name | string | Account name on the provider |
| verified | boolean | Always true here |
| visibility_flags | integer | Profile field privacy flags |
| sort_order | integer | Display position |
Get user¶
GET /users/{user_id}
Returns the partial user object of any account. No relationship with the target is required. User sessions only.
Path parameters¶
| Field | Type | Description |
|---|---|---|
| user_id | snowflake | The target account ID |
Response¶
| Status | Body | Condition |
|---|---|---|
| 200 | partial user object | The account exists |
| 400 | error | user_id is not a number |
| 404 | error NOT_FOUND |
No account has this ID |
The response comes from the TEBHOS user service. It returns the stored avatar hash unchanged (including the a_ prefix) and does not substitute the deleted-account placeholder.
Rate limit¶
100 requests per 10 seconds per client and target, bucket user:read.
Get user profile¶
GET /users/{user_id}/profile
Returns the user profile object. Accepts user sessions and bot tokens. user_id may be @me.
Query parameters¶
| Field | Type | Description |
|---|---|---|
| guild_id? | snowflake | Include the target's membership and per-guild profile in this guild |
| with_mutual_friends? | boolean | Include mutual_friends |
| with_mutual_guilds? | boolean | Include mutual_guilds |
Privacy¶
- Access. Unless the target is a bot or yourself, you must be friends, have a pending friend request in either direction, share a guild, or share a group direct message with the target. Otherwise the request fails with 403
MISSING_ACCESS. - Restriction. The target's profile privacy level decides whether you see the full profile; a restricted profile carries
profile_limited: true. - Fields.
timezone_offsetand each connection are filtered by their profile field privacy flags.
Response¶
| Status | Body | Condition |
|---|---|---|
| 200 | user profile object | The account exists and you may see it |
| 400 | error INVALID_FORM_BODY |
user_id or guild_id is not a snowflake |
| 403 | error MISSING_ACCESS |
No relationship, shared guild or shared group DM with the target |
| 404 | error UNKNOWN_USER |
No account has this ID |
Rate limit¶
100 requests per 10 seconds per caller and target, bucket user:profile.
curl "https://tebhos.com/api/v1/users/1501314428688998182/profile?with_mutual_guilds=true" \
-H "Authorization: Bot $TEBHOS_BOT_TOKEN"
Get profile¶
GET /profile/{user_id}
Returns the TEBHOS profile object of any account. Accepts user sessions and bot tokens. No relationship with the target is required. When the target's profile privacy level restricts you, bio and pronouns are null; other fields are always returned. Use Get user profile for the full privacy rules.
Response¶
| Status | Body | Condition |
|---|---|---|
| 200 | profile object | The account exists |
| 400 | error | user_id is not a number |
| 404 | error NOT_FOUND |
No account has this ID |
Rate limit¶
100 requests per 10 seconds per caller and target, bucket user:profile.
Get user profile card¶
GET /profile/{user_id}/card
Returns the profile card object, which adds mutual guilds and friends, your relationship, note and nickname, visible connections, the timezone offset, and optional per-guild member data. Accepts user sessions and bot tokens.
Query parameters¶
| Field | Type | Description |
|---|---|---|
| server_id? | snowflake | Guild whose member data (roles, joined_at, per-guild profile) is included. Ignored when it is not a number or the account is not a member |
Behaviour¶
- No relationship with the target is required to read the card.
- Unless you are reading your own card, the target is a bot, or you are friends, the target's profile privacy level decides whether the card is restricted. A restricted card nulls
bio,pronounsandpremium_since(inmember_profiletoo), setstimezone_offsetto null, emptiesconnected_accounts, and addsprofile_limited: true. timezone_offsetand each connection are also filtered by their own profile field privacy flags.
Response¶
| Status | Body | Condition |
|---|---|---|
| 200 | profile card object | The account exists |
| 400 | error | user_id is not a number |
| 404 | error NOT_FOUND |
No account has this ID |
curl "https://tebhos.com/api/v1/profile/1501314428688998182/card?server_id=1501314428688998100" \
-H "Authorization: Bearer $TEBHOS_TOKEN"
Check user tag¶
GET /users/check-tag
Reports whether a username and discriminator pair is already taken. User sessions only.
Query parameters¶
| Field | Type | Description |
|---|---|---|
| username | string | Username to check. Compared case-insensitively |
| discriminator | integer | Discriminator to check. Use 0 for a human account |
Your own current tag reports false. The route performs no format validation; see Modify current user for the username rules applied when you actually change it.
Response body¶
| Field | Type | Description |
|---|---|---|
| taken | boolean | Whether another account holds the tag |
Rate limit¶
60 requests per 10 seconds per user, bucket user:check_tag.