Skip to content
Fluxer API

Admin voice

A voice region is a named group of media machines, and a voice server is one machine registered inside it. Together they are the topology Voice places a session into when it joins a voice channel or a call.

No operation here addresses a live session, a participant, or a track. Get voice state counts reports occupancy, and List RTC regions is the caller-facing view of the same regions.

LiveKit is the media transport. Each voice server record names one LiveKit deployment and the API key pair the instance authenticates to it with.

endpoint is that deployment’s signalling URL, a ws:// or wss:// address. Fluxer hands it to the placed session verbatim as the endpoint of Voice Server Update, and the client opens its media connection there. The API rewrites the same value to http:// or https:// for its own room service calls, and it keeps any path prefix.

api_key and api_secret mint the access token the placed session presents. The token is valid for 600 seconds, grants room admission to exactly one room, and has the track sources the member’s permissions allow.

A room is one voice channel. A guild channel uses the room name guild_{guild_id}_channel_{channel_id} and a private call uses dm_channel_{channel_id}.

A participant is one voice connection, identified as user_{user_id}_{connection_id}. One account holding several connections in a channel is several participants. Going live publishes a screen share track from the participant that already exists, so a stream needs no second server, room, or grant.

Four stored fields decide whether a region or a server can be chosen for one placement. Fluxer evaluates the four identically on both records, and it also skips a server whenever is_active is false. It resolves a region first and then a server inside it, so a caller admitted to a region whose servers all refuse it has no access to that region.

allowed_user_ids is evaluated first and on its own. A non-empty list admits only the accounts it names and refuses every other caller whatever the remaining three fields say. An empty list gates nothing.

vip_only, required_guild_features, and allowed_guild_ids are guild gates. When none of the three is set, the record admits every caller that passed the user gate, including a private call, which has no guild. When any of the three is set, the record admits only a placement that has a guild, so a restricted region or server is never selectable for a call or a group direct message.

With a guild present, a guild named by allowed_guild_ids is admitted at once and the other two gates are not consulted. Otherwise vip_only requires the guild to hold the VIP_VOICE guild feature, and required_guild_features requires the guild to hold at least one of the features it names. A guild holding none of them is refused.

A region record has the identity a client sees, the coordinate placement measures distance from, and the eligibility fields described under placement eligibility. It has no capacity, no health, and no server count.

The operator supplies id on creation, and it is the primary key. It is the value a channel stores as its rtc_region and the value Modify call region accepts, so changing it means creating a new region and deleting the old one.

FieldTypeDescription
idstringThe ID of the region, chosen by the operator and never renamed (1-64 characters)
namestringThe name shown for the region in a client (1-100 characters)
emojistringThe emoji the operator configured for the region (1-64 characters)
latitudenumberThe latitude placement measures distance from, in decimal degrees
longitudenumberThe longitude placement measures distance from, in decimal degrees
is_default1booleanWhether automatic placement falls back to this region
vip_only2booleanWhether the guild has to hold VIP_VOICE
required_guild_features2array[string]Guild features that admit a guild, any one of which suffices (max 100)
allowed_guild_ids23array[snowflake]The guilds admitted without consulting the other two guild gates (max 1000)
allowed_user_ids3array[snowflake]The accounts allowed to use the region at all (max 1000)
created_at?ISO8601 timestampTime the region record was created, or null when the stored row has none
updated_at?ISO8601 timestampTime the region record last changed, or null when the stored row has none
servers?4array[Admin voice server object]The servers registered in the region

1 The flag is not exclusive, and setting it on a second region does not clear it on the first. Each node then treats the first region its reload enumerates as the default, and a topology with the flag on no region falls back the same way

2 Setting any of these three makes the region unusable for a private call

3 Duplicate entries collapse and the returned order is not the submitted order

4 Present only on List voice regions and Get voice region, and only when include_servers resolved to true. List voice regions sorts the array by server identifier, and Get voice region returns it in the order the store yields

{
"id": "europe-north",
"name": "Northern Europe",
"emoji": "🇸🇪",
"latitude": 59.33,
"longitude": 18.06,
"is_default": true,
"vip_only": false,
"required_guild_features": [],
"allowed_guild_ids": [],
"allowed_user_ids": [],
"created_at": "2026-02-11T08:14:00.000Z",
"updated_at": "2026-08-02T17:45:31.000Z"
}

A server record names one LiveKit deployment, the API key pair the instance authenticates to it with, and its own copy of the eligibility fields. A server is reachable for placement only when its region is also reachable.

The region_id and server_id pair addresses one server, and a server belongs to exactly one region. The same server identifier can exist in two regions, and moving a server between regions means deleting it and recreating it. Both are operator-chosen strings of 1 to 64 characters, and no operation renames either one.

A server can have its own coordinate. When it does, placement measures distance from that coordinate to pick the closest server for an automatically placed session. When it does not, the server takes no part in distance comparison.

FieldTypeDescription
region_idstringThe ID of the region the server belongs to (1-64 characters)
server_idstringThe ID of the server, unique inside its region (1-64 characters)
endpoint1stringThe LiveKit signalling URL the client opens its media connection to
latitude2?numberThe latitude replacing this server’s region coordinate, in decimal degrees, or null when the region coordinate is used
longitude2?numberThe longitude replacing this server’s region coordinate, in decimal degrees, or null when the region coordinate is used
is_active3booleanWhether the server is in rotation for new placement
vip_onlybooleanWhether the guild has to hold VIP_VOICE
required_guild_featuresarray[string]Guild features that admit a guild, any one of which suffices (max 100)
allowed_guild_ids4array[snowflake]The guilds admitted without consulting the other two guild gates (max 1000)
allowed_user_ids4array[snowflake]The accounts allowed to use the server at all (max 1000)
created_at?ISO8601 timestampTime the server record was created, or null when the stored row has none
updated_at?ISO8601 timestampTime the server record last changed, or null when the stored row has none

1 An instance can configure an internal URL that the API uses for its own room service calls to one designated server, and that URL changes neither the stored value nor the value the session receives

2 The two coordinates are set and cleared together, and a server with only one of them cannot be stored

3 Fluxer skips an inactive server when it resolves a new placement. Server-side moderation of a session already on it keeps working

4 Duplicate entries collapse and the returned order is not the submitted order

{
"region_id": "europe-north",
"server_id": "europe-north-server-1",
"endpoint": "wss://voice.example.com/livekit",
"latitude": null,
"longitude": null,
"is_active": true,
"vip_only": false,
"required_guild_features": [],
"allowed_guild_ids": [],
"allowed_user_ids": [],
"created_at": "2026-02-11T08:15:22.000Z",
"updated_at": "2026-02-11T08:15:22.000Z"
}
GET/v1/admin/voice/regions

Returns every Admin voice region object in ascending display name order. Requires voice:region:list.

FieldTypeDescription
include_servers?1booleanWhether each region has its servers, sorted by server identifier (default false)

1 The value is read as a string and counts as true only for true, True, or 1, so any other value, including yes and TRUE, is false. Supplying the parameter twice makes it an array, which fails validation

FieldTypeDescription
regionsarray[Admin voice region object]Every configured region
StatusBodyCondition
200response bodyThe regions were returned

200 requests per minute for each authenticated user, on the admin:lookup bucket.

GET/v1/admin/voice/regions/{region_id}

Returns one Admin voice region object. Requires voice:region:list.

FieldTypeDescription
region_idstringThe ID of the region (1-64 characters)
FieldTypeDescription
include_servers?12booleanWhether the region has its servers (default true)

1 The default is true here and false on List voice regions

2 The value is read as a string and counts as true only for true, True, or 1, so any other value suppresses the servers

FieldTypeDescription
region1?Admin voice region objectThe region, or null when no region has the identifier

1 An unknown region answers 200 with a null region, so region existence is read from the body

StatusBodyCondition
200response bodyA lookup was performed, whether or not it resolved

200 requests per minute for each authenticated user, on the admin:lookup bucket.

POST/v1/admin/voice/regionsAudit reason

Stores a region and returns it. Requires voice:region:create.

FieldTypeDescription
id1stringThe ID to store the region under (1-64 characters)
namestringThe name shown for the region in a client (1-100 characters)
emojistringThe emoji the operator configured for the region (1-64 characters)
latitudenumberThe latitude placement measures distance from, in decimal degrees
longitudenumberThe longitude placement measures distance from, in decimal degrees
is_default?booleanWhether automatic placement falls back to this region (default false)
vip_only?booleanWhether the guild has to hold VIP_VOICE (default false)
required_guild_features?2array[string]Guild features that admit a guild (max 100 items, default empty)
allowed_guild_ids?array[snowflake]The guilds admitted without consulting the other two guild gates (max 1000, default empty)
allowed_user_ids?array[snowflake]The accounts allowed to use the region at all (max 1000, default empty)

1 The identifier is not checked for collision. Reusing the identifier of an existing region overwrites that record in full, resets its creation time to now, and replaces every one of its collections

2 Each item is 1 to 64 characters. A value that is not a real guild feature is stored as supplied and then matches no guild

FieldTypeDescription
region1Admin voice region objectThe stored region

1 The object has no servers member

StatusBodyCondition
200response bodyThe region was stored

Each node reloads its topology after the write. One Admin audit entry with the action create_voice_region and the target type voice_region records the region identifier and its name in metadata, together with the audit reason.

100 requests per minute for each authenticated user, on the admin:guild:modify bucket.

PATCH/v1/admin/voice/regions/{region_id}Audit reason

Applies a partial update to a region and returns the updated record. Requires voice:region:update.

FieldTypeDescription
region_idstringThe ID of the region (1-64 characters)

Every field is optional and an omitted field is left unchanged. An absent, empty, or whitespace-only body is read as an empty object, which validates and updates nothing but updated_at. A body that does not parse as JSON returns 400 INVALID_FORM_BODY with one element at path body and code INVALID_FORMAT.

FieldTypeDescription
name?stringThe name shown for the region in a client (1-100 characters)
emoji?stringThe emoji the operator configured for the region (1-64 characters)
latitude?numberThe latitude placement measures distance from, in decimal degrees
longitude?numberThe longitude placement measures distance from, in decimal degrees
is_default?booleanWhether automatic placement falls back to this region
vip_only?booleanWhether the guild has to hold VIP_VOICE
required_guild_features?1array[string]Guild features that admit a guild (max 100 items of 1-64 characters each)
allowed_guild_ids?1array[snowflake]The guilds admitted without consulting the other two guild gates (max 1000)
allowed_user_ids?1array[snowflake]The accounts allowed to use the region at all (max 1000)

1 A supplied collection replaces the stored collection outright, so removing one entry means sending the complete remaining set and clearing a collection means sending an empty array

The body has no identifier. An id member in the body is overwritten from the path and never renames the region.

FieldTypeDescription
region1Admin voice region objectThe updated region

1 The object has no servers member. Read the servers with List voice servers or Get voice region

StatusBodyCondition
200response bodyThe region was updated
404error responseNo region has the identifier, returned as UNKNOWN_VOICE_REGION

The write sets updated_at to the time it ran, and each node reloads its topology. One Admin audit entry with the action update_voice_region and the target type voice_region records the region identifier in metadata, together with the audit reason. The entry has no field diff.

100 requests per minute for each authenticated user, on the admin:guild:modify bucket.

DELETE/v1/admin/voice/regions/{region_id}Audit reason

Deletes a region and every server registered in it. Requires voice:region:delete.

FieldTypeDescription
region_idstringThe ID of the region (1-64 characters)
FieldTypeDescription
success1booleanAlways true

1 The value is fixed, so a client reads the status to learn whether the call succeeded

StatusBodyCondition
200response bodyThe region was deleted
404error responseNo region has the identifier, returned as UNKNOWN_VOICE_REGION

Each node reloads its topology once for the whole batch, and an operation that has to reach a deleted server afterwards fails. Sessions already placed in the region are not disconnected by the deletion itself.

One Admin audit entry with the action delete_voice_region and the target type voice_region records the region identifier and its name in metadata, together with the audit reason. No delete_voice_server entry is written for the servers deleted with the region.

100 requests per minute for each authenticated user, on the admin:guild:modify bucket.

GET/v1/admin/voice/regions/{region_id}/servers

Returns every Admin voice server object registered in one region. Requires voice:server:list.

FieldTypeDescription
region_idstringThe ID of the region (1-64 characters)
FieldTypeDescription
servers1array[Admin voice server object]The servers registered in the region

1 A region with no server and an identifier naming no region both answer with an empty array

StatusBodyCondition
200response bodyThe servers were returned

200 requests per minute for each authenticated user, on the admin:lookup bucket.

GET/v1/admin/voice/regions/{region_id}/servers/{server_id}

Returns one Admin voice server object. Requires voice:server:list.

FieldTypeDescription
region_idstringThe ID of the region the server belongs to (1-64 characters)
server_idstringThe ID of the server (1-64 characters)
FieldTypeDescription
server1?Admin voice server objectThe server, or null when the pair resolves to nothing

1 An unknown server answers 200 with a null server, and an unknown region is reported the same way

StatusBodyCondition
200response bodyA lookup was performed, whether or not it resolved

200 requests per minute for each authenticated user, on the admin:lookup bucket.

POST/v1/admin/voice/regions/{region_id}/serversAudit reason

Registers a voice server in a region and returns it. Requires voice:server:create.

FieldTypeDescription
region_idstringThe ID of the region the server belongs to (1-64 characters)
FieldTypeDescription
server_id1stringThe ID to store the server under, unique inside the region (1-64 characters)
endpoint2stringThe LiveKit signalling URL the client opens its media connection to
api_keystringThe LiveKit API key the instance authenticates with (1-256 characters)
api_secretstringThe LiveKit API secret the instance authenticates with (1-256 characters)
latitude?3?numberThe latitude replacing this server’s region coordinate, in decimal degrees, or null to use the region coordinate
longitude?3?numberThe longitude replacing this server’s region coordinate, in decimal degrees, or null to use the region coordinate
is_active?booleanWhether the server is in rotation for new placement (default true)
vip_only?booleanWhether the guild has to hold VIP_VOICE (default false)
required_guild_features?array[string]Guild features that admit a guild (max 100 items of 1-64 characters each, default empty)
allowed_guild_ids?array[snowflake]The guilds admitted without consulting the other two guild gates (max 1000, default empty)
allowed_user_ids?array[snowflake]The accounts allowed to use the server at all (max 1000, default empty)

1 The pair of region and server identifier is not checked for collision. Reusing an existing pair overwrites that record in full, resets its creation time to now, and replaces both stored credentials

2 The value has to parse as a URL. Validation does not constrain the scheme, and the client receives the value unchanged

3 The two coordinates are supplied together and are either both null or both a number. A mismatched pair fails body validation on the latitude path

The body has no region_id. A region_id member in the body is overwritten from the path and cannot register the server under a different region.

FieldTypeDescription
server1Admin voice server objectThe stored server

1 Neither api_key nor api_secret appears on the object

StatusBodyCondition
200response bodyThe server was stored
400error responseA non-URL endpoint or an unpaired coordinate, returned as INVALID_FORM_BODY
404error responseThe identifier names no region, returned as UNKNOWN_VOICE_REGION

Each node reloads its topology after the write. One Admin audit entry with the action create_voice_server and the target type voice_server records the region identifier, the server identifier, and the endpoint in metadata, together with the audit reason. Neither credential is recorded.

100 requests per minute for each authenticated user, on the admin:guild:modify bucket.

PATCH/v1/admin/voice/regions/{region_id}/servers/{server_id}Audit reason

Applies a partial update to a voice server and returns the updated record. Requires voice:server:update.

FieldTypeDescription
region_idstringThe ID of the region the server belongs to (1-64 characters)
server_idstringThe ID of the server (1-64 characters)

Every field is optional and an omitted field is left unchanged. An absent, empty, or whitespace-only body is read as an empty object, which validates and updates nothing but updated_at. A body that does not parse as JSON returns 400 INVALID_FORM_BODY with one element at path body and code INVALID_FORMAT.

FieldTypeDescription
endpoint?stringThe LiveKit signalling URL the client opens its media connection to, which has to parse as a URL
api_key?1stringThe LiveKit API key the instance authenticates with (1-256 characters)
api_secret?1stringThe LiveKit API secret the instance authenticates with (1-256 characters)
latitude?2?numberThe latitude replacing this server’s region coordinate, in decimal degrees, or null to use the region coordinate
longitude?2?numberThe longitude replacing this server’s region coordinate, in decimal degrees, or null to use the region coordinate
is_active?booleanWhether the server is in rotation for new placement
vip_only?booleanWhether the guild has to hold VIP_VOICE
required_guild_features?3array[string]Guild features that admit a guild (max 100 items of 1-64 characters each)
allowed_guild_ids?3array[snowflake]The guilds admitted without consulting the other two guild gates (max 1000)
allowed_user_ids?3array[snowflake]The accounts allowed to use the server at all (max 1000)

1 An omitted credential is left unchanged and a supplied one replaces it. An empty string fails the length bound, so a credential can be replaced but never cleared

2 The two coordinates are supplied together and are either both null or both a number. Sending both as null clears the override and returns the server to its region coordinate

3 A supplied collection replaces the stored collection outright, so removing one entry means sending the complete remaining set and clearing a collection means sending an empty array

The body has no identifiers. A region_id or server_id member in the body is overwritten from the path and cannot move the server to another region.

FieldTypeDescription
serverAdmin voice server objectThe updated server
StatusBodyCondition
200response bodyThe server was updated
404error responseThe pair resolves to no server, returned as UNKNOWN_VOICE_SERVER

The write sets updated_at to the time it ran, and each node reloads its topology and uses the stored credentials for later calls to the server. Setting is_active to false stops new placement and does not move sessions already on the server.

One Admin audit entry with the action update_voice_server and the target type voice_server records the region identifier and the server identifier in metadata, together with the audit reason. The entry records neither credential and no field diff, so a credential rotation is indistinguishable in the audit log from any other update.

100 requests per minute for each authenticated user, on the admin:guild:modify bucket.

DELETE/v1/admin/voice/regions/{region_id}/servers/{server_id}Audit reason

Deletes a voice server. Requires voice:server:delete.

FieldTypeDescription
region_idstringThe ID of the region the server belongs to (1-64 characters)
server_idstringThe ID of the server (1-64 characters)
FieldTypeDescription
success1booleanAlways true

1 The value is fixed, so a client reads the status to learn whether the call succeeded

StatusBodyCondition
200response bodyThe server was deleted
404error responseThe pair resolves to no server, returned as UNKNOWN_VOICE_SERVER

Each node reloads its topology after the removal, and server-side moderation of a session still on that server fails afterwards. Sessions already placed on the server are not disconnected by the deletion itself. The stored credentials are removed with the record and are not recoverable.

One Admin audit entry with the action delete_voice_server and the target type voice_server records the region identifier, the server identifier, and the endpoint the server held in metadata, together with the audit reason.

100 requests per minute for each authenticated user, on the admin:guild:modify bucket.