Quick start
Get VYREX running on Vercel with Discord integration in under 10 minutes.
- Fork or clone the repository to your GitHub account.
- Import to Vercel — go to vercel.com/new, choose your repo, and deploy.
- Add environment variables in Vercel → Project → Settings → Environment Variables. At minimum:
DISCORD_CLIENT_ID,DISCORD_CLIENT_SECRET,DISCORD_BOT_TOKEN,VYREX_OWNER_DISCORD_ID. - Set up Upstash Redis — create a free database at upstash.com and add
UPSTASH_REDIS_REST_URLandUPSTASH_REDIS_REST_TOKEN. - Add OAuth redirect — in the Discord Developer Portal, under your app → OAuth2 → Redirects, add
https://your-domain.vercel.app/oauth-callback. - Redeploy so new env vars take effect. Then open
/dashboardand click Sync from Discord.
Deployment
VYREX is designed for Vercel but runs anywhere Node.js serverless functions are supported.
Vercel (recommended)
The root vercel.json handles all routing. Static files are served from the root directory; API functions live in api/.
{
"rewrites": [
{ "source": "/dashboard", "destination": "/dashboard.html" },
{ "source": "/api/discord-token", "destination": "/api/oauth?__op=discord-token" },
{ "source": "/api/bot-config", "destination": "/api/bot-config" }
]
}
Self-hosted / other providers
Run npm install then serve static files with any web server and set up serverless functions using the provider's Node.js runtime. Ensure all /api/* paths route to the corresponding api/*.js files.
Environment variables
All configuration is done through environment variables. Never commit secrets to your repository.
Discord (required)
| Variable | Required | Description |
|---|---|---|
| DISCORD_CLIENT_ID | Required | Your Discord application's client / application ID |
| DISCORD_CLIENT_SECRET | Required | OAuth2 client secret for token exchange |
| DISCORD_BOT_TOKEN | Required | Bot token from Discord Developer Portal → Bot → Token |
| DISCORD_APPLICATION_ID | Optional | Same as DISCORD_CLIENT_ID — used as fallback |
Access control
| Variable | Required | Description |
|---|---|---|
| VYREX_OWNER_DISCORD_ID | Required | Founder Discord user ID — full platform access |
| VYREX_COOWNER_DISCORD_IDS | Optional | Comma-separated Owner-tier Discord IDs |
| VYREX_STAFF_DISCORD_IDS | Optional | Comma-separated Staff-tier Discord IDs |
| VYREX_DASH_API_KEY | Optional | Long random string for API key auth (no OAuth needed) |
Storage
| Variable | Required | Description |
|---|---|---|
| UPSTASH_REDIS_REST_URL | Recommended | Upstash Redis REST endpoint URL |
| UPSTASH_REDIS_REST_TOKEN | Recommended | Upstash Redis REST token |
| VYREX_ALLOW_MEMORY_FALLBACK | Optional | Set to true to allow in-memory fallback when Redis is unavailable |
Bot setup
Configure your Discord application and bot token for full dashboard integration.
Creating your Discord application
- Go to discord.com/developers/applications and click New Application.
- Under Bot, click Add Bot. Copy the token and add it as
DISCORD_BOT_TOKENon Vercel. - Under OAuth2 → General, copy the Client ID and Client Secret. Add them as
DISCORD_CLIENT_IDandDISCORD_CLIENT_SECRET. - Under OAuth2 → Redirects, add your deployment URL:
https://your-domain.vercel.app/oauth-callback. - Enable Presence Intent, Server Members Intent, and Message Content Intent under Bot → Privileged Gateway Intents.
Inviting the bot
Use the Add to Discord button on the homepage, or generate the invite URL manually:
https://discord.com/api/oauth2/authorize
?client_id=YOUR_CLIENT_ID
&permissions=8
&scope=bot%20applications.commands
Bot branding
Customise your bot's avatar, status, activity, and per-server nicknames from the dashboard.
/api/bot-config every five minutes and applies what is newer than the last thing it applied, so a change made from Discord afterwards (a prefix, a nickname) is not overwritten until you save again here. It needs two values in the bot's .env: DASHBOARD_PUBLIC_URL and VYREX_BOT_SHARED_SECRET, the same secret the panel has. npm run doctor reports whether the sync is on, and >branding-sync applies immediately. Saves are stored in Upstash Redis; without Redis configured they live only in memory and the API answers persisted: false.Global settings
Navigate to Dashboard → Bot Branding. Changes are saved to /api/bot-config (Redis-backed) and your local cache. The bot picks them up on its next poll, within five minutes, or straight away with >branding-sync.
| Setting | Description |
|---|---|
| Avatar URL | PNG/JPG image URL. Your bot must have permissions to change its avatar via the API. |
| Banner URL | Profile banner (requires Discord Nitro on the bot account). |
| Global Nickname | Default display name across all servers (max 32 chars). |
| Brand Colour | Hex colour for generated embeds. Applied to every server that has not set its own colour; one that has keeps it. A value that is not a hex colour is stored as unset rather than replaced with a different one. |
| Activity Type | Watching, Playing, Listening to, Competing in, Streaming, or Custom. |
| Activity Text | Text shown after the activity type in the member list (max 128 chars). |
| Online Status | Online (green), Idle (yellow), Do Not Disturb (red), Invisible. |
Per-server nicknames
In the Per-server Nicknames card, add rows for each server where you want a custom nickname. These are stored separately at /api/bot-config?guildId=SERVER_ID and can be read individually by your bot worker per guild.
POST /api/bot-config with {"guildId": "123", "nickname": "MyBot"} saves a per-guild config. GET /api/bot-config?guildId=123 retrieves it.Commands
VYREX supports both slash commands (/command) and the text prefix (>command). The full, generated list is on the command reference.
Core commands
Every command runs with the text prefix (> by default, changeable per server). The hundred most used are also registered as slash commands and appear in Discord's / picker; everything else is prefix-only. Names and descriptions below are the bot's own.
| Command | Description |
|---|---|
| /help | Interactive command directory, by category |
| /setup | Interactive server configuration wizard |
| /prefix | Show the current command prefix for this server |
| >prefix-set <char> | Change the server command prefix |
| /command <list|disable|enable|channel|role> | Turn commands off, or limit them to certain channels or roles, in this server |
| /ping | Measure runtime latency, gateway heartbeat and connection stability |
| >status | Live platform health, runtime metrics and command pipeline status |
| >reload | Reload commands (owner only) |
| /ban <user> | Permanently remove a member from the server |
| /kick <user> | Forcefully remove a member from the server |
| /mute <user> | Restrict a member from communicating (timeout) |
| /warn <user> | Issue a formal warning to a member |
| /tempban <user> <30m|6h|3d|1w> | Ban for a set time (1 minute to 365 days); the unban is stored, so it still happens after a restart |
| >tempban-list | Every pending automatic unban in this server, with who set it and when it lifts |
| /unban <userId> | Lift a ban early; also cancels its pending automatic unban |
| /sticky <set|show|list|remove> | Pin a message to the bottom of a channel; it moves down as people chat and survives restarts |
| /ticket | Open a support ticket |
| /ticket-transcripts [id] | List archived ticket transcripts, or fetch one by its ticket ID |
| >embed | Create a custom embed message |
Vanity roles
Give a role to members who put your link in their custom status. They hold it while the text is there and lose it when they take it out.
| Command | What it does |
|---|---|
| >vanity text <text> | What to look for in a member's custom status, such as /yourserver |
| >vanity role @role | The role they get while it is there |
| >vanity on / >vanity off | Turn it on or off for this server |
| >vanity status | What is set, and how many members hold it |
| >vanity sync | Apply it to everyone currently online |
>vanity sync after turning it on: statuses only reach the bot as they change, so a quiet member might not be picked up for days otherwise.Welcome & goodbye
One command configures both messages. >welcome test posts exactly what a new member will see, built by the same code the join event runs.
Subcommands
| Command | Description |
|---|---|
| >welcome | Show the current configuration |
| >welcome channel #ch | Where welcome messages go |
| >welcome goodbye-channel #ch | Where goodbye messages go (defaults to the welcome channel) |
| >welcome message <text> | Welcome message body, up to 1,500 characters |
| >welcome title <text> | Welcome embed title |
| >welcome footer <text|off> | Footer line under the welcome embed |
| >welcome banner <https-url|off> | Image under the welcome embed (.png, .jpg, .gif or .webp) |
| >welcome color #hex | Welcome embed colour |
| >welcome goodbye message <text> | Goodbye message body |
| >welcome goodbye title <text> | Goodbye embed title |
| >welcome goodbye color #hex | Goodbye embed colour |
| >welcome goodbye on|off | Turn goodbye messages on or off |
| >welcome enable|disable | Turn welcome messages on or off |
| >welcome test | Post a preview to the current channel |
| >welcome reset | Clear every message, title, footer, banner and colour |
Variables
Any of these work in the message, title and footer, on both the welcome and the goodbye side:
| Variable | Renders as |
|---|---|
| {mention} | A ping of the member |
| {user} · {username} | Their username |
| {tag} · {usertag} | Their tag |
| {id} · {userid} | Their user ID |
| {guild} | The server name |
| {count} · {membercount} | The member count after the join or leave |
| {ordinal} | The member count as an ordinal: 42nd |
| {inviter} | Welcome only: who invited them, when invite tracking is on |
| {joineddays} · {isnew} | Welcome only: account age in days, and yes when it is under a week old |
| {daysinserver} · {roles} | Goodbye only: how long they stayed and the roles they held |
>welcome-card on attaches a rendered image card to the same message. The banner set here is used when the card is off.Moderation
Bans, kicks, mutes, warnings and temporary bans record a moderation case and post to the mod log when one is set (/modlog-set). Member actions respect role hierarchy: the bot never acts on someone above the moderator or above itself. Descriptions are the bot's own. Names shown with / are in the slash picker; the rest run with the prefix.
Members
| Command | What it does |
|---|---|
| /ban <user> [reason] | Permanently remove a member from the server |
| >softban <user> | Ban then immediately unban a member, removing their recent messages |
| /tempban <user> <30m|6h|3d|1w> [reason] | Temporarily ban a user (auto-unbans after duration, survives restarts) |
| >tempban-list | Show all currently active temporary bans and their remaining durations |
| /unban <userId> | Revoke a ban and restore server access |
| >banlist | List all banned users in this server (paginated) |
| /kick <user> [reason] | Forcefully remove a member from the server |
| /mute <user> [duration] | Restrict a member from communicating |
| /unmute <user> | Restore communication for a member |
| >vmute / >vunmute <user> | Server mute a member in voice channels, and remove it again |
| >silentban <user> | Ban a user without sending them a DM or posting a public success message |
| /quarantine <user> | Strip all of a member's roles and isolate them with a Quarantined role (reversible) |
| /unquarantine <user> | Release a quarantined member and restore their saved roles |
| /nick <user> <name> | Change a user's nickname |
| >decancer <user> | Replace a member's unusual/hoisting nickname with a clean one |
>tempban-list shows every pending unban with who set it. Lifting a ban early with /unban cancels the pending one.Warnings, cases and records
| Command | What it does |
|---|---|
| /warn <user> [reason] | Issue a formal warning to a member |
| /warnings <user> | Review warning history for a member |
| >unwarn <user> [index] | Remove one warning from a member by index (or latest) |
| >clear-warnings <user> | Clear all warnings for a member |
| >escalation | View or configure the auto-escalation ladder for warnings |
| /case <id> | View, edit, or delete a moderation case |
| /history <user> | View combined moderation history for a member (warnings + cases + notes) |
| >mod-note <user> <text> | Add a private moderator note to a user record |
| >notes <user> | View private moderator notes for a user |
| /infraction | Issue, review, edit and revoke staff infractions |
| /promotion / /demotion | Move a member up or down the configured rank ladder and record it |
| /staff | Staff records, roster, audit trail and system stats |
Channels
| Command | What it does |
|---|---|
| /purge <amount|all> | Delete messages in bulk — any number, or the whole channel |
| >purge-user <user> [amount] | Delete recent messages from a specific member in this channel |
| /slowmode <seconds> | Adjust the message cooldown for the current channel |
| /lock / /unlock | Lock a channel (prevent sending messages), and resume normal transmission |
| >lockdown | Restrict all message transmission in a channel |
| >lock-server / >unlock-server | Deny or reset @everyone send-message permission across all text channels |
| >raidmode / >unlockall | Lock or unlock every channel at once (fast raid response) |
| >nuke | Clone and replace a channel to purge all history |
Server security
| Command | What it does |
|---|---|
| >antiraid | Configure and monitor automatic raid protection |
| >securityaudit | Score this server's security posture and list what to fix |
| >securityharden | Turn on every protection that is safe to enable automatically |
| /command <disable|channel|role|enable|list> | Turn commands off, or limit them to certain channels or roles, in this server |
/command rule turns an allow into a deny for a server; nothing you set there grants a member a command they could not already run, and the command and help commands themselves cannot be locked out. Naming an alias works — the rule is recorded against the command’s real name, and the reply tells you which one that is.Automod
Eight filters, each its own switch, with thresholds you set per server. Everything is off until you turn it on, and channels or roles you exempt are never scanned. Names and limits below are the bot's own.
Filters
| Filter | What it catches |
|---|---|
| Bad Words Filter | Configurable word list with leet-speak normalisation (>automod badwords to manage it) |
| Link Protection | Blocks http links except allowed domains (>automod whitelist) |
| Invite Blocker | Removes Discord invite links |
| Mention Shield | Removes messages over the mention limit |
| Caps Control | Removes shouted messages |
| Emoji Stabilizer | Removes emoji floods over the emoji limit |
| Zalgo Defense | Removes text stacked with combining marks |
| Phishing Shield | Removes known scam patterns (fake Nitro, gift links, verification bots) |
Thresholds and escalation
| Setting | Range |
|---|---|
| Violation Limit | Strikes before a timeout: 2–20, default 5 |
| Timeout Duration | Minutes: 1–1440, default 10 |
| Burst Limit | Messages in the spam window before spam triggers: 3–20, default 6 |
| Spam Window | Seconds: 5–120, default 10 |
| Max Mentions | 2–30, default 6 |
| Max Emojis | 5–120, default 18 |
Commands
| Command | What it does |
|---|---|
| /automod | Show what is on, with the current thresholds |
| >automod on|off | Turn the whole system on or off for this server |
| >automod panel | Interactive menu to toggle each filter and set every threshold |
| >automod badwords add|remove|list <word> | Manage the word list |
| >automod whitelist add|remove|list <domain> | Domains that Link Protection lets through |
| >automod exempt <#channel|@role> | Channels and roles automod never scans |
| >automod reset | Back to defaults |
| >automod-config punish <none|warn|mute> | What happens after the violation limit |
| >automod-config scanprefix <on|off> | Also scan messages that invoke a bot command (off by default) |
scanprefix is on, so >say and >8ball do not trip the filters. Ordinary messages are always scanned when a filter is on.Tickets
Private channels per request, a panel with a button for members, and an archive that survives the channel. Set a category and a support role with >ticket, then post a panel. Tickets use channel topics and permission overwrites; no dashboard is needed for the core flow.
| Command | What it does |
|---|---|
| /ticket <reason> | Open a support ticket. The reason must be 8+ characters; the channel is named after the member |
| >ticket category <id|name> | Category the ticket channels are created under |
| >ticket supportrole @role | The role that has access to every ticket |
| >ticket limit <1-20> | Open tickets allowed per member |
| >ticket list | Every open ticket |
| >ticketpanel | Post a persistent panel with an Open Ticket button. |
| >ticket-panel [config …] | Post or configure a support ticket panel (custom title, description, author, footer, button; images via HTTPS args, attachments, or env TICKET_PANEL_*). Manage Server. |
| >ticket-add @user / >ticket-remove @user | Add a user to the current ticket, or remove one |
| >ticket-close | Close a ticket — the HTML transcript is posted before the channel is deleted |
| >ticket-list | List open support and application tickets (staff) |
| >ticket-transcript | Export this ticket channel as an HTML transcript (Discord-style layout, all messages and attachment links). Use inside a support or application ticket. |
| /ticket-transcripts [id] | List archived ticket transcripts, or fetch one by its ticket ID. |
| >ticket-setup | The setup guide: panel, member commands, staff export and the recommended layout, in one embed |
Applications and staff trials
An applicant opens a ticket, fills it in, and a reviewer decides. Accepting can grant the role outright, or put them on a probation period first.
| Command | What it does |
|---|---|
| >apply-panel | Post one application panel where members pick a role from a menu |
| >apply-ticket <role> | Open an application ticket for a specific role |
| >apply-accept [role] | Accept the application and grant the role |
| >apply-accept trial [days] | Accept on probation instead — grants the trial role and starts the clock |
| >apply-deny | Deny the application and close the ticket |
| >trial role @role | The role a trial grants |
| >trial days <1-90> | How long a trial runs by default |
| >trial start @user [days] | Grant the trial role and start the clock |
| >trial confirm @user [@role] | They passed — grant the real role and take the trial one off |
| >trial end @user [reason] | They did not — take the trial role back |
| >trial list | Who is on trial, and when each is reviewed |
/ticket-transcripts reads that archive; the support role and anyone with Manage Channels can open it, and it only ever returns this server's tickets.Economy & levels
Gold, XP and reputation per member, with a shop and leaderboards. Members earn XP by chatting and by voice time; the commands below are the ones in the slash picker.
| Command | What it does |
|---|---|
| /balance [user] | View your or another user's balance. |
| /daily | Claim your daily gold and XP reward |
| /work | Work for gold and experience |
| /shop | Browse the VYREX shop and purchase items. |
| /pay <user> <amount> | Transfer gold to another user. |
| /richest | View the richest players |
| /slots <amount> | Bet gold on the slot machine for a chance to win big! |
| /betflip <amount> <heads|tails> | Flip a coin and bet gold on the outcome. |
| /rank [user] | View your level and progress, or another member's. |
| /leaderboard | View the global XP rankings. |
| /profile [user] | Display a comprehensive player identity card. |
| /rep <user> | Endorse a user with reputation points. |
| >track <amount|all> | Stake gold and lock a moving marker on a multiplier zone |
>track are published, not implied. Every strip is the same ten zones shuffled: one 3x, one 2x, two 1.5x and six that pay nothing, so it returns 80% of what goes into it over time. The zone you get is the one the marker was standing on when you pressed — nothing is rolled afterwards. A round nobody locks refunds the stake.>addlevelrole <level> @role grants a role when a member reaches a level. The full economy — jobs, gacha, pets, casino games, crafting — is in the command reference.Voice assistant
VYREX can sit in a voice channel, hear a wake word, answer out loud, and optionally run moderation commands it was asked for by voice. Because it listens to people, the rules about who is told and who can refuse come first.
vc transcript on.Who is told, and how to refuse
- Joining announces itself.
>vc joinreplies in the channel with what the bot is listening for and how to opt out. - So does arriving later. Anyone who walks into the voice channel while a session is live is named once, in the same channel, with the same instruction. A group arriving is announced together rather than one line each.
- Opting out is global and permanent.
>vc optoutmeans the bot never transcribes that person, in any server, until they run>vc optin. The check runs before the audio stream is subscribed to, not after. - Opting out is not announced. Someone who has already opted out is not named on arrival, because they are not being transcribed and the choice is theirs to share.
Commands
| Command | What it does |
|---|---|
| >vc join [#channel] | Join and start listening. Needs Connect and Speak in that channel. |
| >vc leave | Disconnect and stop listening. |
| >vc ask <question> | Ask by typing; the answer is spoken out loud. |
| >vc status | Live diagnostics and latency for the current session. |
| >vc test | End-to-end self-test of the voice pipeline. |
| >vc optout | Never transcribe me, in any server. |
| >vc optin | Undo that. |
| >speak <text> | Say something out loud in the current voice channel. |
| >transcribe | Reply to an audio file to transcribe it. |
Settings (Manage Server)
| Command | What it sets | Default |
|---|---|---|
| >vc mode wake|always|push | When the bot responds | wake |
| >vc wake <phrase> | The wake phrase | hey vyrex |
| >vc voice <name> | The speaking voice | provider default |
| >vc persona <style> | The personality of replies | professional |
| >vc transcript on|off [#channel] | Post what was said to a channel | off unless set |
| >vc actions on|off | Let voice run moderation commands | on |
GROQ_API_KEY (free tier) or DEEPGRAM_API_KEY and restart. Without one the bot can still speak, but it cannot listen. Timing is tunable: VYREX_VOICE_SILENCE_MS (default 800) is the pause that ends an utterance, VYREX_VOICE_MAX_UTTERANCE_MS (default 30000) caps a single one, and VYREX_VOICE_IDLE_TIMEOUT_MS (default 600000) leaves an idle channel.Authentication
VYREX signs in with PKCE-based Discord OAuth only. Sessions are server-backed via Upstash Redis.
Discord OAuth (PKCE)
- User clicks Continue with Discord. The browser generates a 48-byte random code verifier.
- The SHA-256 hash of the verifier (code challenge) is sent to Discord's authorize URL.
- Discord redirects to
/oauth-callbackwith an auth code. - The callback calls
POST /api/discord-token, sending the code + verifier. The server exchanges these for an access token without the client_secret ever touching the browser. - The access token is used to call
GET /users/@meon Discord's API to get the user's ID and email.
Sessions and accounts
Accounts are stored in Upstash Redis under vyrex:acc:<id>. Sessions are 32-byte random tokens stored under vyrex:sess:<token> with a 30-day TTL. Password sign-in is disabled by default; see Auth endpoints.
Tier system
All role checks happen server-side in api/_lib/serverAccountTier.js:
| Tier | Access level | Set via |
|---|---|---|
| Founder | Full platform access including Founder panel | VYREX_OWNER_DISCORD_ID |
| Owner | Team management, system ops, subscriptions | VYREX_COOWNER_DISCORD_IDS |
| Staff | Analytics, logs, admin accounts view | VYREX_STAFF_DISCORD_IDS |
| Member | Dashboard, commands, modules, automations | Everyone else |
Embed builder
Build rich Discord embeds visually and export the JSON to use in any bot.
Using the embed builder
Navigate to Dashboard → Embed Builder. The live preview updates as you type. When done, click Copy JSON to get the payload.
JSON output format
{
"embeds": [{
"color": 5046271,
"author": { "name": "VYREX", "url": "https://vyrex.lastlydevelopments.com" },
"title": "Embed Title",
"description": "Your **markdown** text here.",
"fields": [
{ "name": "Field 1", "value": "Value 1", "inline": true },
{ "name": "Field 2", "value": "Value 2", "inline": true }
],
"footer": { "text": "VYREX Bot" },
"timestamp": "2025-01-01T00:00:00.000Z"
}]
}
Quick presets
8 built-in presets: Welcome, Announcement, Warning, Success, Error, Info, Rules, Event. Click any to load it into the builder.
Team & roles
Manage your platform team using Discord ID allowlists on Vercel environment variables.
Adding team members
- Get the team member's Discord user ID (right-click their name in Discord → Copy User ID, with Developer Mode on).
- Add the ID to
VYREX_COOWNER_DISCORD_IDS(Owner) orVYREX_STAFF_DISCORD_IDS(Staff) on Vercel — comma-separated for multiple IDs. - Redeploy the project. The team member can now sign in with Discord and access their tier-appropriate sections.
VYREX_OWNER_DISCORD_ID. It cannot be shared or transferred.API overview
All VYREX API routes are serverless Node.js functions deployed alongside the static site.
Base URL
https://your-domain.vercel.app/api/
Authentication
API routes accept two auth methods:
- API key:
x-vyrex-api-key: YOUR_DASH_API_KEYheader — full access - Discord OAuth:
Authorization: Bearer DISCORD_ACCESS_TOKEN— access scoped by Discord ID tier
Available routes
| Route | Method | Description |
|---|---|---|
| /api/health | GET | Service health check — no auth required |
| /api/discord-token | POST | Exchange Discord auth code for access token |
| /api/auth-accounts | GET/POST/PUT | User account management and sessions |
| /api/bot-snapshot | GET | Fetch bot's guilds from Discord API |
| /api/bot-config | GET/POST | Bot branding and per-server configuration |
| /api/command-catalog | GET | Search the generated command reference |
| /api/workspace-store | GET/POST | Persist dashboard workspace state to Redis |
| /api/guild-plan | GET/POST | Manage per-guild billing plan |
| /api/connection-status | GET | Configuration and storage health summary |
| /api/connection-selftest | GET | Full self-test with latency measurements |
Auth endpoints
The /api/auth-accounts endpoint handles sessions and admin operations. Sign-in itself goes through Discord OAuth — see Authentication.
POST /api/auth-accounts — Register / Login
Both actions are disabled. VYREX signs in with Discord only, so these return:
403 { "error": "password_auth_disabled" }
Set VYREX_ALLOW_PASSWORD_AUTH=1 on the deployment to re-enable email/password sign-in. It is off by default and should stay off unless you have a specific reason.
POST /api/auth-accounts — Logout
{ "action": "logout" }
Returns: { "ok": true }
GET /api/auth-accounts?me=1
Requires Authorization: Bearer SESSION_TOKEN. Returns the current account and computed tier.
Bot config API
Store and retrieve bot customisation settings per-guild or globally.
GET /api/bot-config
Returns global config. Append ?guildId=SERVER_ID for per-guild config.
POST /api/bot-config — Global
{
"activityType": "watching",
"activityText": "your server",
"onlineStatus": "online",
"brandColor": "#7c3aed",
"globalNick": "VYREX",
"avatarUrl": "https://cdn.example.com/avatar.png"
}
Requires Founder or Owner auth (API key or elevated Discord ID).
POST /api/bot-config — Per-guild
{ "guildId": "1234567890", "nickname": "MyBot", "prefix": "!", "embedColor": "#34d399" }
Requires any valid auth (Discord OAuth or API key).
FAQ
Common questions about VYREX setup and configuration.
Why does /api/bot-snapshot show 0 servers?
The bot snapshot requires DISCORD_BOT_TOKEN set on Vercel and a valid Discord or API key auth header. Sign in with Discord in the dashboard and click Sync from Discord.
My session expires — how do I extend it?
Sessions last 30 days (Redis TTL). The dashboard auto-refreshes the server session if you're active. Re-signing in creates a fresh session.
Can I run multiple bots from one dashboard?
Currently one bot token per deployment. To manage multiple bots, deploy separate instances of VYREX with different environment variables.
How do I enable Stripe billing?
Add STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, STRIPE_PRICE_PRO, and STRIPE_PRICE_PREMIUM to Vercel. The /api/stripe-session handler is ready.
Troubleshooting
Common issues and how to fix them.
"Failed to fetch" on Discord sign-in
The /api/discord-token route is not reachable. Check: (1) the site is deployed on Vercel (not opened as a file), (2) DISCORD_CLIENT_SECRET is set, (3) the redirect URI in Discord Portal matches exactly.
Sessions not persisting across devices
Configure Upstash Redis. Without it, sessions are in-memory and lost on function cold starts.
Bot branding not applying to Discord
The dashboard saves config to /api/bot-config. The bot reads it every five minutes when DASHBOARD_PUBLIC_URL and VYREX_BOT_SHARED_SECRET are set in its .env; npm run doctor in the bot repo tells you whether that sync is on.
Owner/Staff access not working
Make sure you signed in with Discord OAuth. The tier check compares your Discord user ID against the env var allowlists. After adding IDs, redeploy Vercel.