> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/discordplace/discord.place/llms.txt
> Use this file to discover all available pages before exploring further.

# Server Configuration

> Customize the discord.place server using config.yml.

The server configuration lives in `server/config.yml`. This YAML file controls everything from Discord OAuth scopes and bot behaviour to channel IDs, role permissions, and available locales.

<Warning>
  Make sure to fill **all fields ending in `ChannelId`** with real Discord channel IDs from your base guild. Leaving them as placeholders will cause the bot to fail when it tries to post to those channels.
</Warning>

## Full config structure

The file below shows the default values shipped with discord.place:

```yaml server/config.yml theme={null}
discordScopes:
  - 'identify'
  - 'email'
  - 'guilds'
botPresenceStatus: 'online'
rateLimitWhitelist:
  - '957840712404193290'
trustProxy: true
frontendUrl: 'https://discord.place'
backendUrl: 'https://api.discord.place'
docsUrl: 'https://docs.discord.place'
supportInviteUrl: 'https://invite.discord.place'
emojis:
  loading: '<a:loading:1247786499076915252>'
  checkmark: '<:yes:1226129515718381568>'
  pink_heart: '<:heart:1211809043564339290>'
  badges:
    admin: '<:white_admin:1267620006183571530>'
    moderator: '<:white_moderator:1251538987592712345>'
    premium: '<:white_premium:1251538989312249947>'
    verified: '<:white_verified:1251538990524403793>'
  empty_badge_slot: '<:empty_badge_slot:1251541500282798090>'
port:
  frontend: 3000
  backend: 3001
guildId: '1200254872059121764'
guildInviteUrl: 'https://invite.discord.place'
permissions:
  canEditProfilesRoles:
    - '1206032198562742312'
  # ... (full permissions object — see source)
maxServerCountDifference: 50
roles:
  jrModerator: '1206355082883371049'
  moderator: '1267549562957205645'
  headModerator: '1206354879321210900'
  admin: '1206032198562742312'
  premium: '1252335063123628084'
  translator: '1275014710692941896'
excludeCollectionsInBackup:
  - 'botdenies'
  - 'botvotetimeouts'
  - 'servervoteremindermetadas'
  - 'servervotereminders'
  - 'servervotetimeouts'
  - 'evaluateresults'
  - 'githubcaches'
  - 'plans'
customHostnames:
  - 'dsc.lat'
  - 'dsc.gay'
  - 'dsc.wtf'
  - 'dsc.baby'
lemonSqueezy:
  variantIds:
    tripledVotes:
      servers: '421124'
      bots: '421125'
    standedOut:
      servers: '425991'
      bots: '425992'
availableLocales:
  - name: 'English'
    code: 'en'
    flag: '🇺🇸'
    default: true
    countryCode: 'us'
  - name: 'Turkish'
    code: 'tr'
    flag: '🇹🇷'
    countryCode: 'tr'
# Channel IDs (replace all with your own)
emojiQueueChannelId: ''
soundQueueChannelId: ''
reviewQueueChannelId: ''
themeQueueChannelId: ''
reportsQueueChannelId: ''
botQueueChannelId: ''
templateQueueChannelId: ''
webLogsChannelId: ''
testWebhookLogsChannelId: ''
```

## Options reference

### General

<ParamField path="discordScopes" type="string[]" required>
  Discord OAuth2 scopes requested during login. The default set — `identify`, `email`, and `guilds` — is required for the full feature set. Only remove a scope if you are certain the features that depend on it are not used.
</ParamField>

<ParamField path="botPresenceStatus" type="string" default="online">
  Presence status displayed for the Discord bot. Accepted values: `online`, `idle`, `dnd`, `invisible`.
</ParamField>

<ParamField path="rateLimitWhitelist" type="string[]">
  Array of Discord user IDs that are exempt from all rate limits. Add IDs for your admin accounts here.
</ParamField>

<ParamField path="trustProxy" type="boolean" default="true">
  Express [`trust proxy`](https://expressjs.com/en/guide/behind-proxies.html) setting. Set to `true` when running behind a reverse proxy (e.g. nginx, Cloudflare) so that `req.ip` reflects the real client IP instead of the proxy's IP.
</ParamField>

### URLs

<ParamField path="frontendUrl" type="string" required>
  Public URL of the Next.js client (e.g. `https://discord.place`). Used by the server to construct redirect URLs and CORS rules.
</ParamField>

<ParamField path="backendUrl" type="string" required>
  Public URL of the Express API server (e.g. `https://api.discord.place`). Used to construct self-referential API links.
</ParamField>

<ParamField path="docsUrl" type="string" required>
  URL of the documentation site, linked from bot messages and API responses.
</ParamField>

<ParamField path="supportInviteUrl" type="string" required>
  Invite URL for your Discord support server, linked from bot messages and error pages.
</ParamField>

### Bot emojis

<ParamField path="emojis" type="object" required>
  Custom emojis used in bot messages and embeds. Each value is a Discord emoji string in the format `<:name:id>` (static) or `<a:name:id>` (animated). Replace all values with emojis from your own guild.

  | Key                | Description                                  |
  | ------------------ | -------------------------------------------- |
  | `loading`          | Animated loading spinner                     |
  | `checkmark`        | Success / yes indicator                      |
  | `pink_heart`       | Decorative heart emoji                       |
  | `badges.admin`     | Admin badge shown on profiles                |
  | `badges.moderator` | Moderator badge shown on profiles            |
  | `badges.premium`   | Premium badge shown on profiles              |
  | `badges.verified`  | Verified badge shown on profiles             |
  | `empty_badge_slot` | Placeholder shown when a badge slot is empty |
</ParamField>

### Ports

<ParamField path="port.frontend" type="number" default="3000">
  Port the Next.js client runs on. Should match `NEXT_PUBLIC_PORT` in the client's `.env`.
</ParamField>

<ParamField path="port.backend" type="number" default="3001">
  Port the Express server listens on.
</ParamField>

### Base guild

<ParamField path="guildId" type="string" required>
  Discord ID of your base guild. The bot uses this guild for role assignments, channel logging, and other administrative actions.
</ParamField>

<ParamField path="guildInviteUrl" type="string" required>
  Public invite URL for the base guild. Displayed in bot messages and on the website.
</ParamField>

### Permissions

<ParamField path="permissions" type="object" required>
  Maps permission names to arrays of role IDs from the base guild. Permission names ending in `Roles` are role-based (checked against a user's server roles). Permission names without a suffix are user ID-based.

  Replace all role IDs with those from your own guild. The following permission keys are available:

  | Permission key                | Description                                             |
  | ----------------------------- | ------------------------------------------------------- |
  | `canEditProfilesRoles`        | Can edit any user's profile                             |
  | `canDeleteProfilesRoles`      | Can delete any profile                                  |
  | `canDeleteServersRoles`       | Can remove any server listing                           |
  | `canDeleteEmojisRoles`        | Can remove any emoji                                    |
  | `canDeleteBotsRoles`          | Can remove any bot listing                              |
  | `canDeleteReviewsRoles`       | Can delete any review                                   |
  | `canDeleteTemplatesRoles`     | Can delete any template                                 |
  | `canDeleteSoundsRoles`        | Can delete any sound                                    |
  | `canDeleteThemesRoles`        | Can delete any theme                                    |
  | `canApproveEmojisRoles`       | Can approve submitted emojis                            |
  | `canApproveBotsRoles`         | Can approve submitted bots                              |
  | `canApproveReviewsRoles`      | Can approve submitted reviews                           |
  | `canApproveTemplatesRoles`    | Can approve submitted templates                         |
  | `canApproveSoundsRoles`       | Can approve submitted sounds                            |
  | `canApproveThemesRoles`       | Can approve submitted themes                            |
  | `canEditServersRoles`         | Can edit any server listing                             |
  | `canEditBotsRoles`            | Can edit any bot listing                                |
  | `canViewQuarantinesRoles`     | Can view quarantined users/guilds in the dashboard      |
  | `canCreateQuarantinesRoles`   | Can add new quarantine entries                          |
  | `canDeleteQuarantinesRoles`   | Can remove quarantine entries                           |
  | `canViewDashboardRoles`       | Can access the admin dashboard                          |
  | `canDeleteBotDeniesRoles`     | Can delete bot denial records                           |
  | `canRestoreBotDeniesRoles`    | Can restore a denied bot                                |
  | `canViewTimeoutsRoles`        | Can view user timeouts                                  |
  | `canDeleteTimeoutsRoles`      | Can delete timeouts                                     |
  | `canSyncLemonSqueezyPlans`    | Can trigger Lemon Squeezy plan sync (user ID-based)     |
  | `canExecuteEval`              | Can run arbitrary eval commands via bot (user ID-based) |
  | `canExecuteFetchRoles`        | Can trigger a role fetch                                |
  | `canExecuteRefreshCacheRoles` | Can trigger a cache refresh                             |
  | `canExecuteAddPremium`        | Can grant premium to users (user ID-based)              |
  | `canVerifyProfilesRoles`      | Can verify user profiles                                |
  | `canDeleteLinksRoles`         | Can delete profile links                                |
</ParamField>

### Server count validation

<ParamField path="maxServerCountDifference" type="number" default="50">
  Maximum allowed discrepancy between the `server_count` value a bot reports via the stats API and the actual count observed by the Discord bot. Requests exceeding this threshold are rejected. Increase this value if you expect bots with large, rapidly-changing server counts.
</ParamField>

### Roles

<ParamField path="roles" type="object" required>
  Maps logical role names to Discord role IDs from the base guild. Replace each ID with the corresponding role in your own guild.

  | Key             | Description               |
  | --------------- | ------------------------- |
  | `jrModerator`   | Junior moderator role     |
  | `moderator`     | Moderator role            |
  | `headModerator` | Head moderator role       |
  | `admin`         | Administrator role        |
  | `premium`       | Premium subscriber role   |
  | `translator`    | Community translator role |
</ParamField>

### Database backups

<ParamField path="excludeCollectionsInBackup" type="string[]">
  MongoDB collection names to exclude from daily database backups. Use exact collection names as they appear in the database. The defaults exclude ephemeral or easily-regenerated collections such as vote timeouts and evaluation results.
</ParamField>

### Custom hostnames

<ParamField path="customHostnames" type="string[]" required>
  List of custom vanity hostnames for user profiles (e.g. `dsc.lat`). Must match the `customHostnames` list in `client/config.js`. Each hostname must be DNS-pointed to your server and proxied to the correct port via a reverse proxy.
</ParamField>

### Lemon Squeezy

<ParamField path="lemonSqueezy.variantIds" type="object">
  Maps internal product identifiers to Lemon Squeezy variant IDs. If you are using Lemon Squeezy for premium features, create these products/variants in your Lemon Squeezy store and update these IDs.

  | Key                    | Description                               |
  | ---------------------- | ----------------------------------------- |
  | `tripledVotes.servers` | Tripled votes product variant for servers |
  | `tripledVotes.bots`    | Tripled votes product variant for bots    |
  | `standedOut.servers`   | Stand-out listing variant for servers     |
  | `standedOut.bots`      | Stand-out listing variant for bots        |
</ParamField>

### Locales

<ParamField path="availableLocales" type="object[]" required>
  Array of locale objects available on the server. Each object has the following fields:

  | Field         | Type    | Description                                                              |
  | ------------- | ------- | ------------------------------------------------------------------------ |
  | `name`        | string  | Human-readable language name                                             |
  | `code`        | string  | BCP 47 language code matching the JSON filename in `server/src/locales/` |
  | `flag`        | string  | Flag emoji                                                               |
  | `default`     | boolean | Set to `true` on the default locale                                      |
  | `countryCode` | string  | ISO 3166-1 alpha-2 country code                                          |

  See [Localization](/self-hosting/localization) for instructions on adding new languages.
</ParamField>

### Channel IDs

All fields ending in `ChannelId` must be set to real channel IDs from your base guild.

| Field                      | Description                                    |
| -------------------------- | ---------------------------------------------- |
| `emojiQueueChannelId`      | Channel where emoji submission queue is posted |
| `soundQueueChannelId`      | Channel for sound submission queue             |
| `reviewQueueChannelId`     | Channel for review moderation queue            |
| `themeQueueChannelId`      | Channel for theme submission queue             |
| `reportsQueueChannelId`    | Channel where user reports are posted          |
| `botQueueChannelId`        | Channel for bot submission queue               |
| `templateQueueChannelId`   | Channel for template submission queue          |
| `webLogsChannelId`         | Channel for general web server logs            |
| `testWebhookLogsChannelId` | Channel for test webhook event logs            |
