Skip to content

Entrance sounds

An entrance sound is a short audio clip an account plays while it is connected to a voice channel. An account uploads a clip once into its own library, assigns it to a scope, and plays it for the other participants of a voice channel. Voice describes where the feature sits.

Every route on this page is user-only, requires no channel permission, and acts on the caller's own library. A bot token is rejected with 403 ACCESS_DENIED.

TEBHOS Pro

Set entrance sound selection and Play entrance sound require TEBHOS Pro and return 403 FORBIDDEN without it. Listing, uploading, renaming, and deleting clips stay available, so an account whose Pro ended can still manage its library. The feature_voice_entrance_sounds limit key in instance discovery tells the TEBHOS clients whether to show the feature.

Clip limits

Bound Value
Clips per account 8
Decoded clip size 1,048,576 bytes (1 MiB)
Clip duration 100 through 5,200 milliseconds
Display name 1 through 32 characters after trimming

Supported containers

TEBHOS detects the container from the decoded bytes, so a filename, a data: media type, or any other declared type has no effect. The duration is read from the container itself, and a file whose duration cannot be read is rejected.

Detected container Stored extension Stored content type
MP3 (with or without an ID3 tag) mp3 audio/mpeg
Ogg ogg audio/ogg
MP4 or M4A (ftyp box) with an audio track m4a audio/mp4
WAV (RIFF/WAVE) wav audio/wav

Every other format, including FLAC, WebM, Matroska, and AIFF, is rejected.

The decoded bytes are stored exactly as they arrived, under the extension and content type the table assigns.

Entrance sound object

One stored audio clip owned by one account. Every field except name is fixed at upload.

Structure

Field Type Description
id snowflake The ID of the sound
name string The display label (1 through 32 characters)
hash string A content digest of the stored audio, 16 hexadecimal characters. Clips with identical audio have the same hash
extension string The stored extension: mp3, ogg, m4a, or wav
content_type string The MIME type the clip is stored and served with
duration_ms integer The measured duration in milliseconds
size_bytes integer The decoded size in bytes
url string The absolute URL the clip is fetched from, https://cdn.tebhos.com/entrance-sounds/{user_id}/{hash}.{extension} on the public instance. It needs no credential
created_at ISO8601 timestamp The time the clip was uploaded

Example

{
  "id": "1501314428688998182",
  "name": "airhorn",
  "hash": "9f2c41ab77de0135",
  "extension": "mp3",
  "content_type": "audio/mpeg",
  "duration_ms": 1240,
  "size_bytes": 20416,
  "url": "https://cdn.tebhos.com/entrance-sounds/1490000000000000000/9f2c41ab77de0135.mp3",
  "created_at": "2026-09-20T09:12:04.118+00:00"
}

Entrance sound selection object

One scope and the clip assigned to it.

Structure

Field Type Description
scope_id string The scope the selection applies to
sound_id snowflake The clip assigned to that scope

A scope with no assigned sound has no selection object.

Example

{
  "scope_id": "guild:1490000000000000123",
  "sound_id": "1501314428688998182"
}

Entrance sound scopes

The TEBHOS clients use these scope values:

Value Description
global Applies wherever no narrower scope is selected
guilds Applies in guild voice channels
dms Applies in direct message and group calls
guild:{guild_id} Applies in one named guild

TEBHOS stores scope_id as sent and does not validate its format, so use one of these values. Scopes are only a client-side convention: Play entrance sound names the clip explicitly, and the client decides which selection applies to a channel.

List entrance sounds

GET /users/@me/entrance-sounds

Returns the current account's complete entrance sound library together with its per-scope selections.

Response body

Field Type Description
sounds array[entrance sound object] Every clip the account owns, at most 8
selections array[entrance sound selection object] Every scope with a sound assigned

Both members are always present, and both arrays are empty for an account that has uploaded nothing.

Rate limit

30 requests per minute for each user, on the user:entrance_sound:list bucket.

Upload entrance sound

POST /users/@me/entrance-sounds

Decodes, validates, and stores one audio clip in the current account's library, and returns 201 with the created entrance sound object.

JSON body

Field Type Description
name string The display label, trimmed, 1 through 32 characters
audio base64 string The audio bytes, base64 encoded. A data:...;base64, prefix is accepted and discarded

Validation

Every failure below returns 400 INVALID_FORM_BODY with a human-readable message. The checks run in this order.

Failure Condition
Name The trimmed name is empty or longer than 32 characters
Quota The library already holds 8 clips
Encoding audio is not valid base64, or decodes to nothing
Size The decoded bytes exceed 1,048,576 bytes
Format The bytes match no supported container, or their duration cannot be read
Duration The duration is above 5,200 ms or below 100 ms

A request body larger than the upload limit (about 1.4 MiB of base64 plus 64 KiB) is rejected before validation.

Response

Status Body Condition
201 entrance sound object The clip was stored
400 error response The name or audio fails validation

Side effects

The operation assigns no scope and emits no Gateway Dispatch. Uploading the same bytes twice creates two library entries with the same hash and url. Deleting one leaves the other usable.

Rate limit

5 requests per 5 minutes for each user, on the user:entrance_sound:upload bucket.

Rename entrance sound

PATCH /users/@me/entrance-sounds/{sound_id}

Changes the display label of one clip and returns the updated entrance sound object.

Path parameters

Field Type Description
sound_id snowflake The ID of the sound

JSON body

Field Type Description
name string The replacement label, trimmed, 1 through 32 characters

Response

Status Body Condition
200 entrance sound object The clip was renamed
400 error response sound_id is not a number, or the name is empty or longer than 32 characters (BAD_REQUEST)
404 error response The account owns no such clip (NOT_FOUND)

A clip owned by another account is reported exactly like one that never existed.

Side effects

Only the label changes. Selections pointing at the clip keep pointing at it. No Gateway Dispatch is emitted.

Rate limit

20 requests per minute for each user, on the user:entrance_sound:mutate bucket, shared with Delete entrance sound and Set entrance sound selection.

Delete entrance sound

DELETE /users/@me/entrance-sounds/{sound_id}

Deletes one clip from the current account's library, clears every selection that pointed at it, and returns 204 with an empty body. An unknown clip, or a clip owned by another account, is a successful no-op.

Path parameters

Field Type Description
sound_id snowflake The ID of the sound

Response

Status Body Condition
204 empty The clip was deleted, or no owned clip existed
400 error response sound_id is not a number

Side effects

The clip and every selection naming it are removed. The stored audio file is removed too, unless another clip in the library has the same content. No Gateway Dispatch is emitted.

Rate limit

20 requests per minute for each user, on the shared user:entrance_sound:mutate bucket.

Set entrance sound selection

PUT /users/@me/entrance-sound-selections

Assigns a clip to one scope, or clears that scope, and returns 204 with an empty body. A scope that already has a sound is overwritten. Requires TEBHOS Pro.

JSON body

Field Type Description
scope_id string The scope to write
sound_id? ?snowflake The clip to assign. Null, an omitted field, or a value that is not a number clears the scope

TEBHOS does not check that sound_id names a clip in the caller's library. A client SHOULD send only IDs returned by List entrance sounds.

Response

Status Body Condition
204 empty The selection was written or cleared
403 error response The account does not have TEBHOS Pro

Side effects

One clip can be selected in any number of scopes. No Gateway Dispatch is emitted, so the caller's other sessions learn about the change only by listing the library again.

Rate limit

20 requests per minute for each user, on the shared user:entrance_sound:mutate bucket.

Play entrance sound

POST /voice/channels/{channel_id}/entrance-sound

Tells every other account connected to a voice channel to play the caller's clip, and returns 204 with an empty body. The caller must hold a voice connection in that channel and must own the clip. Requires TEBHOS Pro. Emits ENTRANCE_SOUND_PLAY.

Recipients fetch and play the clip locally from the URL in the event.

Path parameters

Field Type Description
channel_id snowflake The ID of the voice channel or private call channel

JSON body

Field Type Description
sound_id snowflake The clip to play, from the caller's own library

Response

Status Body Condition
204 empty TEBHOS attempted a Dispatch to every other connected account
400 error response channel_id or sound_id is not a number, the caller holds no voice connection in the channel, or the account owns no such clip (BAD_REQUEST)
403 error response The account does not have TEBHOS Pro
404 error response The channel does not exist

Connection is the only authorisation

TEBHOS evaluates no channel permission and checks no guild membership. The connection check runs before the clip is looked up.

Side effects

TEBHOS sends one ENTRANCE_SOUND_PLAY Dispatch to every other account holding a voice state in the channel, at most once for each account, and never to the caller. The Dispatch is addressed to the account, so every session that account holds receives it, including sessions that are not in the channel. A client filters on channel_id.

Rate limit

3 requests per 30 seconds for each user and channel, on the voice:entrance_sound:play bucket.