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, then assigns it to a scope: globally, in guild voice channels, in private calls, or in one named guild. Voice defines voice state and placement.
Every route on this page is user-only, requires no permission, and acts on the caller’s own library.
Clip limits
Section titled “Clip limits”Every bound below is a fixed constant of the instance, and none is resolved from an account limit rule.
| Bound | Value |
|---|---|
| Clips per account | 8 |
| Decoded clip size1 | 1048576 bytes |
| Encoded upload payload1 | 1398134 characters |
| Clip duration2 | 100 through 5200 milliseconds |
| Display name | 1 through 32 characters after normalisation |
1 The character bound is the 1 MiB decoded ceiling expressed in base64 with 32 characters of slack, so it is the bound an oversized payload reaches first
2 Only Upload entrance sound applies the lower bound
The instance discovery document publishes a feature_voice_entrance_sounds limit key. The FiveCord client reads that key to decide whether it opens the clip upload dialog and whether it calls Play entrance sound after it connects to a voice channel. No route on this page checks it, so a library can be read, written, and played back regardless of its resolved value.
Supported containers
Section titled “Supported containers”FiveCord detects the container from the decoded bytes, so a filename, a data: media type, or any other declared type has no effect on the result. The detected container resolves to a stored extension, and every other input fails with ENTRANCE_SOUND_INVALID_FORMAT.
| Detected container | Stored extension | Stored content type |
|---|---|---|
| MP3, MPEG1 | mp3 | audio/mpeg |
| Ogg2 | ogg | audio/ogg |
| MP4, QuickTime, AAC3 | m4a | audio/mp4 |
| WAV | wav | audio/wav |
1 An MPEG program stream resolves here as well as bare MPEG audio
2 An audio Ogg and a video Ogg both resolve here
3 The container alone decides this row, so an MP4 or QuickTime file with a video stream is accepted as long as a duration can be measured from it. A bare AAC stream outside an MP4 container is not detected and is rejected
FLAC, WebM, Matroska, AIFF, 3GPP, AVI, FLV, WMV, MPEG-TS, and every image type resolve to no extension and are rejected.
Entrance sound object
Section titled “Entrance sound object”One stored audio clip owned by one account. Every field except name is fixed at upload, and id is the only handle the other routes accept.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| id | snowflake | The ID of the sound |
| name | string | The display label shown for the clip (1-32 characters) |
| hash1 | string | The content digest of the stored audio, 16 hexadecimal characters |
| extension | string | The stored extension, one of mp3, ogg, m4a, and wav, chosen by the detected container |
| content_type | string | The MIME type the clip is stored and served with, derived from extension |
| duration_ms2 | integer | The measured duration in milliseconds (0-5200) |
| size_bytes | integer | The decoded size in bytes (0-1048576) |
| url3 | string | The absolute CDN URL the clip is fetched from |
| created_at | ISO8601 timestamp | The time the clip was uploaded |
1 A content hash. Clips with identical audio have the same hash
2 Measured from the decoded audio and rounded to the nearest millisecond
3 Built as /entrance-sounds/{user_id}/{hash}.{extension} on the instance’s media endpoint. The route that serves it accepts no credential, so anyone holding the URL can fetch the audio
Example
Section titled “Example”{ "id": "1501314428688998182", "name": "airhorn", "hash": "9f2c41ab77de0135", "extension": "mp3", "content_type": "audio/mpeg", "duration_ms": 1240, "size_bytes": 20416, "url": "https://cdn.example.com/entrance-sounds/1490000000000000000/9f2c41ab77de0135.mp3", "created_at": "2026-08-31T09:12:04.118Z"}Entrance sound selection object
Section titled “Entrance sound selection object”One scope and the clip assigned to it.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| scope_id | string | Entrance sound scope the selection applies to |
| sound_id | snowflake | The clip assigned to that scope |
A scope with no assigned sound has no selection object. Clearing a scope deletes its entry.
Example
Section titled “Example”{ "scope_id": "guild:1490000000000000123", "sound_id": "1501314428688998182"}Entrance sound scopes
Section titled “Entrance sound scopes”| 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, where the ID is 1 through 20 digits |
scope_id must match one of these forms exactly. Any other value fails with the validation code INVALID_FORMAT at the scope_id path.
List entrance sounds
Section titled “List entrance sounds”GET/v1/users/@me/entrance-soundsReturns the current account’s complete entrance sound library together with its per-scope selections.
Response body
Section titled “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. A selection always names a sound present in sounds.
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | response body | Library was returned |
Rate limit
Section titled “Rate limit”30 requests per minute for each authenticated user, on the user:entrance_sound:list bucket.
Upload entrance sound
Section titled “Upload entrance sound”POST/v1/users/@me/entrance-soundsDecodes, validates, and stores one audio clip in the current account’s library, and returns the created entrance sound object.
JSON body
Section titled “JSON body”| Field | Type | Description |
|---|---|---|
| name1 | string | The display label shown for the clip (1-32 characters) |
| audio2 | base64 string | The audio bytes of the clip, base64 encoded (1-1398134 characters) |
1 Trimmed before its length is measured
2 A data: URI prefix is accepted and discarded, and only the part after the first comma is measured and decoded
Invisible characters in name are not stripped and count towards the 32 character bound.
Validation
Section titled “Validation”Every failure below returns 400 INVALID_FORM_BODY. A response can contain more than one field error.
| Failure | Validation code | Path |
|---|---|---|
| The field is absent or is a literal empty string1 | INVALID_FORMAT | name or audio |
| The normalised name is empty or longer than 32 characters | STRING_LENGTH_INVALID | name |
| The encoded payload is empty or longer than 1398134 characters2 | BASE64_LENGTH_INVALID | audio |
| The payload is not valid base64 | INVALID_BASE64_FORMAT | audio |
| The library already holds 8 clips | ENTRANCE_SOUND_QUOTA_REACHED | audio |
| The decoded bytes exceed 1048576 bytes | ENTRANCE_SOUND_SIZE_EXCEEDS_LIMIT | audio |
| The bytes resolve to no supported container, or their duration cannot be measured | ENTRANCE_SOUND_INVALID_FORMAT | audio |
| The measured duration is above 5200 ms or below 100 ms | ENTRANCE_SOUND_DURATION_EXCEEDS_LIMIT | audio |
| The validated clip could not be written to storage | FAILED_TO_UPLOAD_IMAGE | audio |
1 An empty string is read as null under input normalisation, and neither field accepts null
2 Measured after any data: prefix is discarded, so a value that is whitespace only, or that ends at its first comma, has zero payload characters and fails here
FiveCord checks the first four rows before the quota, so an account already holding 8 clips receives BASE64_LENGTH_INVALID or INVALID_BASE64_FORMAT for a malformed or too-long payload.
The validation entry has no member naming which duration bound the clip crossed.
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 201 | entrance sound object | Clip was stored |
| 400 | error response | Name or audio fails validation |
Side effects
Section titled “Side effects”The operation assigns no scope and emits no Gateway Dispatch.
Rate limit
Section titled “Rate limit”5 requests per 5 minutes for each authenticated user, on the user:entrance_sound:upload bucket.
Rename entrance sound
Section titled “Rename entrance sound”PATCH/v1/users/@me/entrance-sounds/{sound_id}Changes the display label of one clip and returns the updated entrance sound object.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| sound_id | snowflake | The ID of the sound |
JSON body
Section titled “JSON body”| Field | Type | Description |
|---|---|---|
| name1 | string | Replacement display label (1-32 characters) |
1 Required, and normalised and bounded exactly as the name of Upload entrance sound
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | entrance sound object | Clip was renamed |
| 400 | error response | Name normalises to the empty string or exceeds 32 characters and the request returns STRING_LENGTH_INVALID at the name path, or the account owns no such clip and the request returns ENTRANCE_SOUND_NOT_FOUND at the sound_id path |
Side effects
Section titled “Side effects”Only the label changes. The stored audio is untouched, and every selection pointing at the clip keeps pointing at it. FiveCord emits no Gateway Dispatch.
Rate limit
Section titled “Rate limit”20 requests per minute for each authenticated user, on the user:entrance_sound:mutate bucket, which is shared with Delete entrance sound and Set entrance sound selection.
Delete entrance sound
Section titled “Delete entrance sound”DELETE/v1/users/@me/entrance-sounds/{sound_id}Deletes one clip from the current account’s library, clears every scope 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
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| sound_id | snowflake | The ID of the sound |
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 204 | empty | Clip was deleted, or no owned clip existed |
Side effects
Section titled “Side effects”The clip and every selection naming it are removed from the library. No Gateway Dispatch is emitted.
Rate limit
Section titled “Rate limit”20 requests per minute for each authenticated user, on the shared user:entrance_sound:mutate bucket.
Set entrance sound selection
Section titled “Set entrance sound selection”PUT/v1/users/@me/entrance-sound-selectionsAssigns one of the account’s clips to one scope, or clears that scope, and returns 204 with an empty body. Each call addresses exactly one scope, and a scope that already has a sound is overwritten.
JSON body
Section titled “JSON body”| Field | Type | Description |
|---|---|---|
| scope_id | string | Entrance sound scope to write (1-32 characters) |
| sound_id1 | ?snowflake | The clip to assign, or null to clear the scope |
1 Required. An explicit null clears the scope, succeeds even when the scope had no selection, and looks up no clip
A guild:{guild_id} scope does not require current guild membership. A non-null sound_id must name a clip the account owns.
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 204 | empty | Selection was written or cleared |
| 400 | error response | Scope is unrecognised and the request returns INVALID_FORMAT at the scope_id path, or the account owns no such clip and the request returns ENTRANCE_SOUND_NOT_FOUND at the sound_id path |
Side effects
Section titled “Side effects”FiveCord writes or removes the scope’s selection. One clip can be selected in any number of scopes at once. The operation emits no Gateway Dispatch, so the caller’s other sessions learn about the change only by listing the library again.
Rate limit
Section titled “Rate limit”20 requests per minute for each authenticated user, on the shared user:entrance_sound:mutate bucket.
Play entrance sound
Section titled “Play entrance sound”POST/v1/voice/channels/{channel_id}/entrance-soundTells every other account connected to a voice channel to play the caller’s chosen clip and returns 204 with an empty body. The caller must already hold a voice state in that channel and must own the clip. Emits an ENTRANCE_SOUND_PLAY Gateway event.
Recipients fetch and play the clip locally from the URL in the event.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| channel_id | snowflake | The ID of the voice channel the clip is played in |
JSON body
Section titled “JSON body”| Field | Type | Description |
|---|---|---|
| sound_id | snowflake | The clip to play, drawn from the caller’s own library |
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 204 | empty | FiveCord attempted a Dispatch to every other connected account |
| 400 | error response | Caller holds no voice state in the channel, including when the channel does not exist, and the request returns ENTRANCE_SOUND_INVALID_SCOPE at the channel_id path, or the account owns no such clip and the request returns ENTRANCE_SOUND_NOT_FOUND at the sound_id path |
An ID naming no channel is refused exactly like a channel the caller is not connected to. The connection check runs before the clip is looked up, so a caller who is not connected never learns whether the named clip exists.
Side effects
Section titled “Side effects”FiveCord 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. A recipient whose Dispatch fails is skipped, and the request still returns 204.
FiveCord addresses the Dispatch 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
Section titled “Rate limit”3 requests per 30 seconds for each authenticated user and channel ID, on the voice:entrance_sound:play::user_id::channel_id bucket.