Skip to content
FiveCord Docs

Experiments

An experiment is an instance-wide rollout that an operator configures. For each account, FiveCord works out from that configuration whether the account is in the rollout and which settings the account receives. The single route on this page resolves every experiment the server defines and returns them in one envelope, together with the polling cadence they share. This server defines voice_noise_suppression, whose placement protocol Voice defines, and domain_migration.

Every assignment is advice. A client that ignores one behaves as it does with the rollout off, and no route and no Gateway event reports what a client actually ran.

One resolution of every defined experiment against one account. Every field is present on every response.

FieldTypeDescription
poll_interval_secondsintegerSeconds to wait before revalidating, from 60 through 86400
poll_jitter_percentintegerThe largest random offset added to or subtracted from the wait, as a percentage of the wait, from 0 through 50
assignmentsassignment map objectOne entry for each experiment the server defines

Every account on the instance receives the same poll_interval_seconds and poll_jitter_percent. One request refreshes every experiment.

One entry per experiment. The envelope reports this object even when it is empty.

FieldTypeDescription
voice_noise_suppression?noise suppression assignment objectThe caller’s noise suppression assignment
domain_migration?domain migration assignment objectThe caller’s web domain migration assignment

Ignore unknown experiments and treat a missing experiment as off.

This server version writes voice_noise_suppression on every response, including while a rollout is disabled. The disabled value is the first resolution outcome below, which reports enabled false and the stored config_version, so a client that compares config_version with the value from its previous response can see that an operator saved the configuration, even while the rollout stays disabled, and needs no second request for it.

Noise suppression runs in the client, on the microphone track, before that track is published. FiveCord processes no audio for it. The registry is closed, and a backend outside it is not a value this API produces or accepts.

ValueDescription
noneNo processing
standardThe browser or platform suppressor the client already has
gateA noise gate keyed on input level
speexThe Speex preprocessor
rnnoiseThe RNNoise recurrent model
gtcrnThe GTCRN model
deep_filterThe DeepFilterNet model

A client MUST treat a backend absent from enabled_backends as unavailable, including one named by backend or by a guild override.

One resolution of the instance noise suppression rollout against one account. Every field is present whenever the key is written.

FieldTypeDescription
enabledbooleanWhether the rollout is running on this instance
config_versionintegerThe revision of the instance configuration this assignment was resolved from
user_targetedbooleanWhether the caller is inside the rollout
backend?stringThe backend the caller applies, and null where the caller is not targeted
source?stringWhich rule targeted the caller, one of user_rule or canary, and null where the caller is not targeted
guild_overridesarray[guild override object]Per-guild backend replacements that apply to the caller
enabled_backendsarray[string]The backends the client MAY run
allow_user_overridebooleanWhether the account’s own stored choice replaces backend
suppression_strengthintegerSuppression strength from 0 through 100, which only a backend that reads it applies

config_version identifies the configuration revision. It can change without changing the caller’s assignment.

The outcomes below set user_targeted to false, and they differ in what else they report.

  1. The rollout is off. enabled is false, enabled_backends and guild_overrides are empty, and allow_user_override is false.
  2. The operator has excluded the caller. enabled is true, and every other field is as in the first outcome.
  3. The caller was not drawn. enabled is true, and enabled_backends, guild_overrides, and allow_user_override all hold their configured values.

A caller is drawn either by the operator’s allowlist, which sets source to user_rule, or by the sampled share of the account population, which sets source to canary. A caller that is drawn while backend is absent from enabled_backends is reported as not drawn, with user_targeted false and both backend and source null.

A client branches on user_targeted rather than on enabled_backends, because the third outcome keeps the array populated. A guild_overrides entry applies in its guild whether or not the caller was drawn.

config_version reports the stored revision in all outcomes, the rollout being off included.

One backend replacement scoped to one guild. While the caller is connected to a voice channel of that guild, the override’s backend replaces the assignment’s backend.

FieldTypeDescription
guild_idsnowflakeThe guild the replacement applies in
backendstringThe backend to run in that guild

An override naming a backend that is absent from enabled_backends is dropped before the response is written, so every entry is runnable.

One resolution of the instance web domain migration rollout against one account. This server version writes the key on every response.

FieldTypeDescription
enabledbooleanWhether the caller’s web client moves to the new web origin

A caller is drawn either by the operator’s allowlist or by the sampled share of the account population. enabled is false in every other case, the rollout being off included.

Only the official web client acts on this assignment, and only on its legacy origins. Every other client ignores it. The logged-out share and the instance-wide switch are published in the instance discovery document instead, because a client that holds no credential cannot read this route.

GET/v1/experimentsBot

Resolves every defined experiment for the caller and returns an experiment assignments object. The response is derived per account, so it is never shared between accounts.

Experiment assignments object.

StatusBodyCondition
200response bodyThe envelope was resolved
304emptyThe request sent a matching If-None-Match
FieldTypeDescription
If-None-Match?stringAn ETag from an earlier response to this route

A client sends the ETag it last received. FiveCord compares it against the tag of the envelope it just resolved and answers 304 with no body on a match. * matches any current tag. A weak comparison is used, so a W/ prefix on either side does not defeat the match.

FieldTypeDescription
ETagstringA strong tag over the envelope body, sent on 200 and on 304
Cache-ControlstringThe literal value private, no-cache
VarystringThe literal value Authorization, replaced by Origin where the cross-origin policy echoed an allowed origin

The ETag changes when the response changes. Treat it as an opaque value.

ETag is listed in Access-Control-Expose-Headers and If-None-Match in Access-Control-Allow-Headers, so a cross-origin client reads the tag and revalidates with it.

A client reads this route once per session and then again every poll_interval_seconds, offset by a random amount up to poll_jitter_percent of that interval in either direction. It sends the last ETag on every request after the first. A client MUST NOT poll faster than the lower end of that jitter range.

Until the first successful response, use 300 seconds with 15 percent jitter.

60 requests per 10 seconds for each authenticated user, on the default bucket.