REST API

REST API

Meww.me exposes two API layers on the same Fastify server (default port 2555).

Architecture

 Frontend (React)           Fastify (port 2555)                   Bot Core
┌──────────────┐   HTTP    ┌─────────────────────────┐
│              │ ────────► │ /api/*  (Dashboard Proxy)│
│ Dashboard    │ � - �──────── │   Session auth (cookie)  │
│              │           │                          │
│              │   WS      │ Socket.IO server         │
│              │ � - �──────── │   Real-time events       │
└──────────────┘           └────────────┬─────────────┘
                                        │ internal HTTP
                           ┌────────────▼─────────────┐
                           │ /v1/*  (Internal API)     │
                           │   Token auth (header)     │
                           └──────────────────────────┘

Internal API (/v1/*)

The internal API is used by the DashboardPlugin proxy and can also be called directly by external services. It requires an Authorization header matching config.features.RestAPI.auth.

Authentication

Authorization: your_secret_api_token

The token is set in config.yml under features.RestAPI.auth.

IP/Domain Whitelist

If features.RestAPI.whitelist is non-empty, only requests from listed domains or IPs are accepted. The whitelist checks the Host header and x-forwarded-for.

Player Endpoints

MethodPathDescription
GET/v1/players/:guildIdGet player state for a guild
POST/v1/players/Create a new player (join voice + optional play)
PATCH/v1/players/:guildIdControl player (pause, volume, loop, seek, skip, etc.)
DELETE/v1/players/:guildIdStop and destroy the player
GET/v1/players/:guildId/voice/:userIdCheck if a user is in the bot's voice channel
GET/v1/players/:guildId/member/:userIdCheck voice channel membership

Search

MethodPathDescription
GET/v1/search?identifier=...&source=...&requester=...&guildId=...Search for tracks. Sources: ytsearch, scsearch, spotify, etc.

User Endpoints

MethodPathDescription
GET/v1/user/:userId/statsGet user listening statistics
GET/v1/user/:userId/premiumGet user premium status and per-feature access flags
GET/v1/user/:userId/playlistsGet user's playlists

Guild Endpoints

MethodPathDescription
GET/v1/guild/:guildId/statsGet guild statistics
GET/v1/guild/:guildId/activityGet guild activity feed
GET/v1/guild/:guildId/settingsGet guild settings
PATCH/v1/guild/:guildId/settingsUpdate guild settings

Global Endpoints

MethodPathDescription
GET/v1/commandsList all registered bot commands
GET/v1/top-serversTop 12 servers by member count
GET/v1/global-statsGlobal bot statistics
GET/v1/system-statusSystem health and status

Dashboard Proxy API (/api/*)

The dashboard proxy layer is registered via DashboardPlugin. It wraps the internal API with session-based authentication (Discord OAuth2 cookie) and adds dashboard-specific endpoints.

Authentication

Session-based via mewwme-dash.sid cookie. The cookie is set after successful Discord OAuth2 login.

Auth Endpoints

MethodPathAuthDescription
GET/auth/discord-Start Discord OAuth2 flow (redirects to Discord)
GET/auth/discord/callback-OAuth2 callback (exchanges code for token, creates session)
GET/auth/meSessionGet current authenticated user (includes isAdmin flag)
POST/auth/logoutSessionDestroy session
GET/auth/debug-Debug info (environment, cookies, CORS settings)

Guild Management

MethodPathAuthDescription
GET/api/guildsSessionList user's mutual guilds with the bot (includes hasBot flag)
GET/api/guilds/:guildId/voiceSessionCheck if user is in the bot's voice channel
GET/api/guilds/:guildId/voice-membersSessionList all non-bot members in the bot's voice channel
GET/api/guilds/:guildId/activitySessionGet guild activity feed
GET/api/guild/:guildId/statsSessionGet guild statistics

Player Control

MethodPathAuthDescription
GET/api/player/activeSessionFind the user's active player (checks all mutual guilds)
GET/api/player/:guildIdSessionGet player state
POST/api/playerSessionCreate player (body: { guildId })
PATCH/api/player/:guildIdSessionControl player (body: control commands)
DELETE/api/player/:guildIdSessionStop player
GET/api/player/:guildId/memberSessionCheck voice channel membership

Search

MethodPathAuthDescription
GET/api/search?identifier=...&source=...&guildId=...SessionSearch for tracks

User Data

MethodPathAuthDescription
GET/api/statsSessionUser stats (listening + profile data)
GET/api/playlists/accessSessionCheck playlist feature access
GET/api/commandsPublicList all bot commands
GET/api/top-serversPublicTop servers
GET/api/global-statsPublicGlobal bot statistics
GET/api/system-statusPublicSystem status

AI Chat

MethodPathAuthDescription
POST/api/ai-chatSessionSend a message to AI chat (body: { message, guildId })
GET/api/ai-chat/historySessionGet user's chat history (last 20 messages)
POST/api/ai-chat/clearSessionClear user's chat history

Liked Songs

MethodPathAuthDescription
GET/api/liked-songsSessionGet user's liked songs
POST/api/liked-songsSessionAdd a liked song
DELETE/api/liked-songs/:trackUriSessionRemove a liked song

Premium

MethodPathAuthDescription
GET/api/premium/statusSessionGet user premium status
POST/api/premium/claimSessionClaim premium for a guild
POST/api/premium/unclaimSessionUnclaim premium from a guild

Admin Endpoints

These endpoints require the user to be a bot admin (ADMIN array or OWNER_ID).

MethodPathAuthDescription
GET/api/admin/premiumAdminList all premium entries
POST/api/admin/premium/userAdminGrant premium to a user
POST/api/admin/premium/guildAdminGrant premium to a guild
DELETE/api/admin/premium/:idAdminRemove a premium entry
GET/api/admin/maintenanceAdminGet maintenance status
POST/api/admin/maintenanceAdminToggle maintenance mode
GET/api/admin/blacklistAdminList blacklisted users/guilds
POST/api/admin/blacklistAdminAdd to blacklist
DELETE/api/admin/blacklist/:idAdminRemove from blacklist
GET/api/admin/profiles/pendingAdminGet pending bot profile changes
POST/api/admin/profiles/:guildId/approveAdminApprove a profile change
POST/api/admin/profiles/:guildId/rejectAdminReject a profile change

Helpdesk/Ticket Admin

MethodPathAuthDescription
GET/api/admin/ticket/configAdminGet ticket configuration
POST/api/admin/ticket/toggleAdminToggle ticket system
GET/api/admin/ticket/guild/:guildIdAdminGet guild ticket data
POST/api/admin/ticket/setupAdminCreate ticket setup
PUT/api/admin/ticket/setupAdminUpdate ticket setup
DELETE/api/admin/ticket/setup/:idAdminDelete ticket setup
GET/api/admin/ticket/historyAdminGet ticket history
POST/api/admin/ticket/closeAdminClose a ticket
POST/api/admin/ticket/deleteAdminDelete a ticket
DELETE/api/admin/ticket/all/:guildIdAdminDelete all ticket data for a guild

Webhook Server (Express - port 2444)

The Express WebServer handles external service webhooks on a separate port.

MethodPathAuthDescription
POST/voteTop.gg Webhook SecretTop.gg vote webhook
POST/kofiKo-fi Verification TokenKo-fi payment/subscription webhook
GET/lastfm-Last.fm OAuth callback

Top.gg Vote Webhook

Receives vote notifications. The Authorization header must match features.WebServer.TOPGG_VOTELOGS.TopGgWebhookSecret. Logs votes to the configured LogVoteChannelID.

Ko-fi Webhook

Receives payment and subscription events. The request body verification_token must match KoFi.VerificationToken in config. Processes:

  • One-time donations
  • Subscription creation
  • Subscription renewal
  • Subscription cancellation

Last.fm Callback

Handles the OAuth callback from Last.fm after a user authorizes the bot to scrobble on their behalf.


Response Format: Premium Status

GET /api/user/premium or GET /v1/user/:userId/premium

{
  "isPremium": false,
  "isOwner": false,
  "isAdmin": false,
  "hasAccess": false,
  "voteUrl": "https://top.gg/bot/928966154817523723/vote",
  "access": {
    "filters": true,
    "twentyFourSeven": true,
    "autoplay": true,
    "lastfm": true,
    "spotify": true,
    "songRequest": true,
    "language": true,
    "statusVoiceChannel": true,
    "prefix": true,
    "djRole": true,
    "controlButton": true,
    "playlist": true
  },
  "requirements": {
    "filters": "Voter",
    "twentyFourSeven": "Voter",
    "autoplay": "Voter",
    "lastfm": "Voter",
    "spotify": "Voter",
    "songRequest": "Voter",
    "language": "Voter",
    "statusVoiceChannel": "Voter",
    "prefix": "Voter",
    "djRole": "Voter",
    "controlButton": "Voter",
    "playlist": "Voter"
  }
}

The access object contains booleans for each gated feature. The requirements object contains the configured access level for each feature. The frontend uses these to render access overlays.