API reference
Voice
Voice channels, through a LiveKit server. Only while voice_enabled on GET /instance is true; otherwise every voice operation answers 403 voice_disabled. Joining returns a short-lived LiveKit token for one room (the channel ID) whose grants follow the caller's permissions. Who is in which channel is the voice state, sent as the gateway event voice_state_update (VoiceState, channel_id: null when someone leaves) to members who can view the channel. A user is in at most one voice channel at a time.
Every path is relative to https://api.palloo.app/v1.
Send a bot token as Authorization: Bearer palloo_bot_... unless the operation says otherwise; see Authentication.
Try it
Send real requests to https://api.palloo.app/v1 from this page. Open Try it under an operation, fill in its fields and send it.
A bot token is a password.
Anyone who has it can act as your bot. Use a test bot in a test server, never a production bot. The token stays in this tab's memory only: it is not saved, and it goes to the API and nowhere else. Reloading or leaving the page forgets it.
Starts with palloo_bot_. People's tokens are refused here.
On this page
Join voice channel
/channels/{id}/voice
Bot token: Call it with a bot token (people can call it too).
Join a voice channel and get a LiveKit token for it.
Needs View Channel and Connect in the channel. Members with Move Members ignore the
channel's user_limit; everyone else gets 409 voice_channel_full when it is reached.
A caller already in another voice channel of any server leaves it: their old LiveKit
connection is removed and voice_state_update is sent for both channels. A caller who was
moved here by a moderator joins without Connect or the user limit.
The token is valid for 2 minutes and only for connecting to url. Its identity is the
caller's user ID and its only room is the channel ID. It can publish the microphone only
with Speak (and while not server muted or deafened), the camera and screen share only
with Video, and subscribe unless server deafened; it can never publish data or change its
own metadata. Joining twice replaces the session: the newer LiveKit connection wins.
The caller can make 10 joins at once, then 1 every 2 seconds.
Try it: POST /channels/{id}/voice
Sends the bot token from the top of this page.
Prefilled from the example above. Replace the placeholder values; unknown fields are refused.
Request
POST https://api.palloo.app/v1/channels/{id}/voice
curl command
Response
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| id Required | path | string |
Channel ID. |
Request body
application/json:
JoinVoiceRequest
| Field | Type | Description |
|---|---|---|
| self_mute | boolean | default false |
| self_deaf | boolean | default false |
{
"self_mute": false,
"self_deaf": false
}
Responses
- 200
-
Joined. Connect to
urlwithtoken.Body: VoiceJoin
Example response (200) { "url": "string", "token": "string", "expires_at": "2026-10-15T09:00:00Z", "voice_state": { "community_id": "01J9ZQ3V5K8M2N4P6R8T0W2Y4A", "channel_id": "string", "user_id": "01J9ZQ3V5K8M2N4P6R8T0W2Y4A", "session_id": "string", "mute": false, "deaf": false, "self_mute": false, "self_deaf": false, "self_video": false, "self_stream": false, "joined_at": "2026-10-15T09:00:00Z" }, "bitrate": 0, "can_speak": false, "can_video": false, "voice_activity": false, "priority_speaker": false } - 400
-
invalid_body.Body: Error
- 401
-
unauthenticated: the bearer token is missing, invalid or expired.Body: Error
WWW-Authenticateheader. - 403
-
voice_disabled(voice is off here, or thevoiceflag is not on for this server),missing_permission(no Connect) ortimed_out(timed-out members cannot join voice). The flag is checked after Connect, so only members who could otherwise join learn whether a server has it.Body: Error
- 404
-
channel_not_found: no such channel, or the caller is not a member of its community or cannot view the channel.Body: Error
- 409
-
channel_not_voice(a text channel, category, thread or DM) orvoice_channel_full(the channel'suser_limitis reached).Body: Error
- 429
-
rate_limited: too many attempts. Every operation a bot calls is also limited per bot (50 at once, then 50 per second), so any authenticated operation can answer this to a bot. Changes to a community's structure (creating or changing the community, channels, roles, member roles, overwrites, invites, kicks, bans, timeouts, report updates and actions, and bots) are also limited per caller (30 at once, then 1 per second) and per community (60 at once, then 1 per second), and creating communities per caller (10 at once, then 1 every 5 minutes).Body: Error
Retry-Afterheader. - 500
-
internal: an unexpected server error. Details are only in server logs.Body: Error
List voice states
/communities/{id}/voice-states
Bot token: Call it with a bot token (people can call it too).
Who is in the server's voice channels the caller can view.
For the first load and after a gateway reconnect; voice_state_update keeps it current. Ordered by channel, then by when each user joined.
Try it: GET /communities/{id}/voice-states
Sends the bot token from the top of this page.
Request
GET https://api.palloo.app/v1/communities/{id}/voice-states
curl command
Response
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| id Required | path | string |
Community ID. |
Responses
- 200
-
The voice states.
Body: array of VoiceState
Example response (200) [ { "community_id": "01J9ZQ3V5K8M2N4P6R8T0W2Y4A", "channel_id": "string", "user_id": "01J9ZQ3V5K8M2N4P6R8T0W2Y4A", "session_id": "string", "mute": false, "deaf": false, "self_mute": false, "self_deaf": false, "self_video": false, "self_stream": false, "joined_at": "2026-10-15T09:00:00Z" } ] - 401
-
unauthenticated: the bearer token is missing, invalid or expired.Body: Error
WWW-Authenticateheader. - 403
-
voice_disabled.Body: Error
- 404
-
community_not_found: no such community, or the caller is not a member. The two cases are indistinguishable on purpose.Body: Error
- 429
-
rate_limited: too many attempts. Every operation a bot calls is also limited per bot (50 at once, then 50 per second), so any authenticated operation can answer this to a bot. Changes to a community's structure (creating or changing the community, channels, roles, member roles, overwrites, invites, kicks, bans, timeouts, report updates and actions, and bots) are also limited per caller (30 at once, then 1 per second) and per community (60 at once, then 1 per second), and creating communities per caller (10 at once, then 1 every 5 minutes).Body: Error
Retry-Afterheader. - 500
-
internal: an unexpected server error. Details are only in server logs.Body: Error
Update my voice state
/communities/{id}/voice-states/@me
Bot token: Call it with a bot token (people can call it too).
Set the caller's self mute and self deafen.
Sends voice_state_update. Self deafen does not imply self mute on the server; clients set both, as Discord does. The caller can make 20 changes at once, then 2 per second.
Try it: PATCH /communities/{id}/voice-states/@me
Sends the bot token from the top of this page.
Prefilled from the example above. Replace the placeholder values; unknown fields are refused.
Request
PATCH https://api.palloo.app/v1/communities/{id}/voice-states/@me
curl command
Response
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| id Required | path | string |
Community ID. |
Request body
application/json:
UpdateMyVoiceStateRequest
(required)
| Field | Type | Description |
|---|---|---|
| self_mute | boolean | |
| self_deaf | boolean |
{
"self_mute": false,
"self_deaf": false
}
Responses
- 200
-
The caller's voice state.
Body: VoiceState
Example response (200) { "community_id": "01J9ZQ3V5K8M2N4P6R8T0W2Y4A", "channel_id": "string", "user_id": "01J9ZQ3V5K8M2N4P6R8T0W2Y4A", "session_id": "string", "mute": false, "deaf": false, "self_mute": false, "self_deaf": false, "self_video": false, "self_stream": false, "joined_at": "2026-10-15T09:00:00Z" } - 400
-
invalid_body.Body: Error
- 401
-
unauthenticated: the bearer token is missing, invalid or expired.Body: Error
WWW-Authenticateheader. - 403
-
voice_disabled.Body: Error
- 404
-
community_not_found: no such community, or the caller is not a member. The two cases are indistinguishable on purpose.Body: Error
- 409
-
not_in_voice: the caller is not in a voice channel of this server.Body: Error
- 429
-
rate_limited: too many attempts. Every operation a bot calls is also limited per bot (50 at once, then 50 per second), so any authenticated operation can answer this to a bot. Changes to a community's structure (creating or changing the community, channels, roles, member roles, overwrites, invites, kicks, bans, timeouts, report updates and actions, and bots) are also limited per caller (30 at once, then 1 per second) and per community (60 at once, then 1 per second), and creating communities per caller (10 at once, then 1 every 5 minutes).Body: Error
Retry-Afterheader. - 500
-
internal: an unexpected server error. Details are only in server logs.Body: Error
Leave voice
/communities/{id}/voice-states/@me
Bot token: Call it with a bot token (people can call it too).
Leave the voice channel the caller is in, in this server.
Removes the caller's LiveKit connection and sends voice_state_update with channel_id: null. Leaving when not in voice is not an error.
Try it: DELETE /communities/{id}/voice-states/@me
Sends the bot token from the top of this page.
Request
DELETE https://api.palloo.app/v1/communities/{id}/voice-states/@me
curl command
Response
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| id Required | path | string |
Community ID. |
Responses
- 204
-
Left, or was not in voice.
- 401
-
unauthenticated: the bearer token is missing, invalid or expired.Body: Error
WWW-Authenticateheader. - 403
-
voice_disabled.Body: Error
- 404
-
community_not_found: no such community, or the caller is not a member. The two cases are indistinguishable on purpose.Body: Error
- 429
-
rate_limited: too many attempts. Every operation a bot calls is also limited per bot (50 at once, then 50 per second), so any authenticated operation can answer this to a bot. Changes to a community's structure (creating or changing the community, channels, roles, member roles, overwrites, invites, kicks, bans, timeouts, report updates and actions, and bots) are also limited per caller (30 at once, then 1 per second) and per community (60 at once, then 1 per second), and creating communities per caller (10 at once, then 1 every 5 minutes).Body: Error
Retry-Afterheader. - 500
-
internal: an unexpected server error. Details are only in server logs.Body: Error
Moderate voice state
/communities/{id}/voice-states/{userID}
Bot token: Call it with a bot token (people can call it too).
Server mute, server deafen, move or disconnect a member in voice.
As Discord's member update. mute needs Mute Members and deaf needs Deafen Members in
the channel the member is in. channel_id needs Move Members in that channel and, to move
them, Connect and Move Members in the destination, which the member must be able to view;
null disconnects them. The member's client sees its own voice_state_update with the
new channel and joins it; LiveKit permissions change at once. Server mute and deafen stay
with the member when they leave voice or the server, until someone clears them. A body
without mute, deaf or channel_id is invalid_body, and a member in a voice channel
the caller cannot view answers not_in_voice, as if they were not in voice. Each change is recorded
in the moderation log (voice.mute, voice.deafen, voice.move, voice.disconnect)
and uses the structural change rate limits. Their details: channel_id, the channel the
member was in, plus mute or deaf (the new value) or to_channel_id (the destination).
Try it: PATCH /communities/{id}/voice-states/{userID}
Sends the bot token from the top of this page.
Prefilled from the example above. Replace the placeholder values; unknown fields are refused.
Request
PATCH https://api.palloo.app/v1/communities/{id}/voice-states/{userID}
curl command
Response
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| id Required | path | string |
Community ID. |
| userID Required | path | string |
The member's user ID. |
Request body
application/json:
ModerateVoiceStateRequest
(required)
| Field | Type | Description |
|---|---|---|
| mute | boolean | |
| deaf | boolean | |
| channel_id | string or null | Move the member to this voice channel, or disconnect them with null. |
{
"mute": false,
"deaf": false,
"channel_id": "string"
}
Responses
- 200
-
The member's voice state after the change (
channel_id: nullafter a disconnect).Body: VoiceState
Example response (200) { "community_id": "01J9ZQ3V5K8M2N4P6R8T0W2Y4A", "channel_id": "string", "user_id": "01J9ZQ3V5K8M2N4P6R8T0W2Y4A", "session_id": "string", "mute": false, "deaf": false, "self_mute": false, "self_deaf": false, "self_video": false, "self_stream": false, "joined_at": "2026-10-15T09:00:00Z" } - 400
-
invalid_body.Body: Error
- 401
-
unauthenticated: the bearer token is missing, invalid or expired.Body: Error
WWW-Authenticateheader. - 403
-
voice_disabled,missing_permissionortimed_out.Body: Error
- 404
-
community_not_found,member_not_foundorchannel_not_found(the destination).Body: Error
- 409
-
not_in_voice(the member is not in a voice channel of this server) orchannel_not_voice(the destination).Body: Error
- 429
-
rate_limited: too many attempts. Every operation a bot calls is also limited per bot (50 at once, then 50 per second), so any authenticated operation can answer this to a bot. Changes to a community's structure (creating or changing the community, channels, roles, member roles, overwrites, invites, kicks, bans, timeouts, report updates and actions, and bots) are also limited per caller (30 at once, then 1 per second) and per community (60 at once, then 1 per second), and creating communities per caller (10 at once, then 1 every 5 minutes).Body: Error
Retry-Afterheader. - 500
-
internal: an unexpected server error. Details are only in server logs.Body: Error