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_tokenThe 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
| Method | Path | Description |
|---|---|---|
| GET | /v1/players/:guildId | Get player state for a guild |
| POST | /v1/players/ | Create a new player (join voice + optional play) |
| PATCH | /v1/players/:guildId | Control player (pause, volume, loop, seek, skip, etc.) |
| DELETE | /v1/players/:guildId | Stop and destroy the player |
| GET | /v1/players/:guildId/voice/:userId | Check if a user is in the bot's voice channel |
| GET | /v1/players/:guildId/member/:userId | Check voice channel membership |
Search
| Method | Path | Description |
|---|---|---|
| GET | /v1/search?identifier=...&source=...&requester=...&guildId=... | Search for tracks. Sources: ytsearch, scsearch, spotify, etc. |
User Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /v1/user/:userId/stats | Get user listening statistics |
| GET | /v1/user/:userId/premium | Get user premium status and per-feature access flags |
| GET | /v1/user/:userId/playlists | Get user's playlists |
Guild Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /v1/guild/:guildId/stats | Get guild statistics |
| GET | /v1/guild/:guildId/activity | Get guild activity feed |
| GET | /v1/guild/:guildId/settings | Get guild settings |
| PATCH | /v1/guild/:guildId/settings | Update guild settings |
Global Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /v1/commands | List all registered bot commands |
| GET | /v1/top-servers | Top 12 servers by member count |
| GET | /v1/global-stats | Global bot statistics |
| GET | /v1/system-status | System 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
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /auth/discord | - | Start Discord OAuth2 flow (redirects to Discord) |
| GET | /auth/discord/callback | - | OAuth2 callback (exchanges code for token, creates session) |
| GET | /auth/me | Session | Get current authenticated user (includes isAdmin flag) |
| POST | /auth/logout | Session | Destroy session |
| GET | /auth/debug | - | Debug info (environment, cookies, CORS settings) |
Guild Management
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/guilds | Session | List user's mutual guilds with the bot (includes hasBot flag) |
| GET | /api/guilds/:guildId/voice | Session | Check if user is in the bot's voice channel |
| GET | /api/guilds/:guildId/voice-members | Session | List all non-bot members in the bot's voice channel |
| GET | /api/guilds/:guildId/activity | Session | Get guild activity feed |
| GET | /api/guild/:guildId/stats | Session | Get guild statistics |
Player Control
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/player/active | Session | Find the user's active player (checks all mutual guilds) |
| GET | /api/player/:guildId | Session | Get player state |
| POST | /api/player | Session | Create player (body: { guildId }) |
| PATCH | /api/player/:guildId | Session | Control player (body: control commands) |
| DELETE | /api/player/:guildId | Session | Stop player |
| GET | /api/player/:guildId/member | Session | Check voice channel membership |
Search
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/search?identifier=...&source=...&guildId=... | Session | Search for tracks |
User Data
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/stats | Session | User stats (listening + profile data) |
| GET | /api/playlists/access | Session | Check playlist feature access |
| GET | /api/commands | Public | List all bot commands |
| GET | /api/top-servers | Public | Top servers |
| GET | /api/global-stats | Public | Global bot statistics |
| GET | /api/system-status | Public | System status |
AI Chat
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /api/ai-chat | Session | Send a message to AI chat (body: { message, guildId }) |
| GET | /api/ai-chat/history | Session | Get user's chat history (last 20 messages) |
| POST | /api/ai-chat/clear | Session | Clear user's chat history |
Liked Songs
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/liked-songs | Session | Get user's liked songs |
| POST | /api/liked-songs | Session | Add a liked song |
| DELETE | /api/liked-songs/:trackUri | Session | Remove a liked song |
Premium
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/premium/status | Session | Get user premium status |
| POST | /api/premium/claim | Session | Claim premium for a guild |
| POST | /api/premium/unclaim | Session | Unclaim premium from a guild |
Admin Endpoints
These endpoints require the user to be a bot admin (ADMIN array or OWNER_ID).
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/admin/premium | Admin | List all premium entries |
| POST | /api/admin/premium/user | Admin | Grant premium to a user |
| POST | /api/admin/premium/guild | Admin | Grant premium to a guild |
| DELETE | /api/admin/premium/:id | Admin | Remove a premium entry |
| GET | /api/admin/maintenance | Admin | Get maintenance status |
| POST | /api/admin/maintenance | Admin | Toggle maintenance mode |
| GET | /api/admin/blacklist | Admin | List blacklisted users/guilds |
| POST | /api/admin/blacklist | Admin | Add to blacklist |
| DELETE | /api/admin/blacklist/:id | Admin | Remove from blacklist |
| GET | /api/admin/profiles/pending | Admin | Get pending bot profile changes |
| POST | /api/admin/profiles/:guildId/approve | Admin | Approve a profile change |
| POST | /api/admin/profiles/:guildId/reject | Admin | Reject a profile change |
Helpdesk/Ticket Admin
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/admin/ticket/config | Admin | Get ticket configuration |
| POST | /api/admin/ticket/toggle | Admin | Toggle ticket system |
| GET | /api/admin/ticket/guild/:guildId | Admin | Get guild ticket data |
| POST | /api/admin/ticket/setup | Admin | Create ticket setup |
| PUT | /api/admin/ticket/setup | Admin | Update ticket setup |
| DELETE | /api/admin/ticket/setup/:id | Admin | Delete ticket setup |
| GET | /api/admin/ticket/history | Admin | Get ticket history |
| POST | /api/admin/ticket/close | Admin | Close a ticket |
| POST | /api/admin/ticket/delete | Admin | Delete a ticket |
| DELETE | /api/admin/ticket/all/:guildId | Admin | Delete all ticket data for a guild |
Webhook Server (Express - port 2444)
The Express WebServer handles external service webhooks on a separate port.
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /vote | Top.gg Webhook Secret | Top.gg vote webhook |
| POST | /kofi | Ko-fi Verification Token | Ko-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.