API#

The general API response is made up of a JSON string, containing the status of the request, if it succeeded (success), or if it raised an error (error) and also a data object containing the requested information, or more details about the error. Usually a response looks like:

    {
        "status": "success",
        "data": data from the request
    }

Error Codes#

Error Description Code
No User Found The token in the auth cookie was missing or is invalid 1
Wrong Key The key to start the authorization was wrong 2
Discord Oauth Exception Discord Oauth token was wrong or missing required permissions 3
Not Connected This API route requires a connection to a guild, which has Meta installed 4
Not Playing A song or video needs to play for this route to work 5
Invalid Args The given args in the request were defined wrong 6
Json Decode Error The JSON given in the request was formatted wrong 7
No Results Query for the songs didnt yield any results 8
Equalizer Disabled The equalizer is disabled on this guild, therefore equalizer requests doesn't work 9
Neutral DJ You need to be at least a DJ to perform this request 10
No Playlist Key The key for the playlist is missing or was wrong 11
Meta Playlist Needed This request requires the playlist to be a Meta playlist 12
Url Playlist Needed This request requires the playlist to be a Url playlist 13
To Many The user already has more then 10 playlists 14
Name Exists The given name already exists for another playlist 15
No Guild Id The given guild ID doesn't belong to a guild, which has Meta installed 16
No Guild Permission This request requires the user to have specific guild permissions 17
No Guild Member The user isn't part of the given guild, therefore the request didnt succeed 18

An example error respond would be

     {
        "status": "error",
        "data": {
            "message": "Your token given in the cookies wasn't found or is invalid, get a new one through the token request",
            "code": "1",
        }
    }

Warn#

If the status of the request is called warn, the request was stopped, by the fact, that the user is a neutral DJ and therefore needs other people to vote. The required votes message is then stored in the content part of the request.

     {
        "status": "warn",
        "data": {
            "message": "Neutral DJ Vote started",
            "content": "At least 50% of the channel members need to vote",
        }
    }

Auth#

To start the auth flow the user needs to be redirected to the route:

GET /auth/redirect?url= url to be redirected

Returns another redirect to a discord authorization window

after the user then successfully authorizes the application, he will be automatically redirected to:

GET /auth/login?code= discord authorization code &state= url to be redirected

Redirects the user to the given redirect url with an additional URL-Parameter added, which has the key token and a matching temporary user token as value. If the state parameter is missing or empty the result will be:

{
    "token": _temporary user token_
}

then the application needs to call the following route with the new temporary token, to finish the authorization:

GET /auth/flow?token= temporary user token

Sets a cookie, containing the real user token to access the API routes

To log out a user just call the route:

GET /auth/logout

Returns true when logged out

Generate an invitation link for the bot

GET /auth/invite

Invite link as a string

User#

To get user information, like name or icon use:

GET /user/me
{
    "name": user name,
    "id": user id,
    "icon": icon url,
    "identifier": user identifier
}

The current connection of a user can be received through:

GET /user/connection
{
    "guild": {
        "name": name,
        "icon" icon url,
        "id": guild id
    },
    "channel": {
        "name": channel name,
        "id": channel id
    },
    "dj": true / neutral / false,
    "equalizer_change": true / false,
    "volume": {
        "limit": 1000,
        "change": true / false,
        "step": 10
    }
}

User stats can be retrieved through:

GET /user/stats
{
    "tracks_added": tracks added,
    "tracks_listen": tracks you listen for more than half of their duration,
    "time_voice": time in a voicechannel in s,
    "time_online": time online in s,
    "time_idle": time idle in s,
    "time_dnd": time dnd in s,
    "time_listen": time listen to tracks in s
}

Guilds#

To get the guilds of a user use the route:

GET /guilds/guilds
{
    [
        {            
            "id": guild id,
            "name": guild 1 name,
            "icon": icon url,
            "admin": true / false,
            "manage_guild": true / false,
            "dj": true / neutral / false,
            "meta": true / false
        },
        {            
            "id": guild id,
            "name": guild 2 name,
            "icon": icon url,
            "admin": true / false,
            "manage_guild": true / false,
            "dj": true / neutral / false,
            "meta": true / false
        } ...
    ]
}

Guild#

To get the general info of the guild:

GET /guild/ guild_id /info
{
    "id": guild id,
    "name": guild name,
    "icon": icon url,
    "admin": true / false,
    "manage_guild": true / false,
    "dj": true / neutral / false,
    "channels": 
    [
        {
            "name": channel 1 name,
            "id": channel id,
            "voice": true / false,
            "text": true / false
        },
        {
            "name": channel 2 name,
            "id": channel id,
            "voice": true / false,
            "text": true / false
        } ...
    ],
    "users": amount of users,
    "owner": 
    {
        "name": owner name,
        "id": owner id,
        "color": hex color of owner,
        "icon": icon url,
        "identifier": owner identifier
    },
    "roles": 
    [
        {
            "name": role 1 name,
            "id": role id ,
            "color": hex color of role,
        },
        {
            "name": role 2 name,
            "id": role id ,
            "color": hex color of role,
        } ...
    ]
}

For a list of the settings:

GET /guild/ guild_id /settings
{
    "volume": {
        "limit": volume limit,
        "default": default volume,
        "change": if the volume can be changed (true / false),
        "step": volume step size
    },
    "player": {
        "shuffle": if auto shuffle is enabled (true / false),
        "repeat": if auto repeat is enabled (true / false),
        "24h": if 24h mode is enabled (true / false),
        "search": the default search engine one of ["yt:", "sp:", "sc:", "tw:", "pl:", "mt:", "dz:", "np:", "am:"],
        "timeout": player timeout,
        "ensure": if someone needs to be in the same voicechannel as Meta (true / false),
        "equalizer": {
            "change": if the equalizer can be changed (true / false),
            "default": a list of the default equalizer with 15 bands [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
        },
        "fallback": if the player falls back to YouTube search (true / false)
    },
    "blacklist": {
        "words": words on the blacklist,
        "enabled": if the blacklist is enabled (true / false)
    },
    "dj": {
        "neutral": {
            "users": 
            [
                {
                    "name": user 1 name,
                    "id": user id,
                    "color": hex color of user,
                    "icon": icon url,
                    "identifier": user identifier
                },
                {
                    "name": user 2 name,
                    "id": user id,
                    "color": hex color of user,
                    "icon": icon url,
                    "identifier": user identifier
                } ...
            ],
            "roles": 
            [
                {
                    "name": role 1 name,
                    "id": role id ,
                    "color": hex color of role,
                },
                {
                    "name": role 2 name,
                    "id": role id ,
                    "color": hex color of role,
                } ...
            ],
            "type": the neutral type one of ["tt", "iv", "pt"],
            "value": neutral dj value,
            "everyone": if everyone is a neutral dj (true / false)
        },
        "default": {
            "users": 
            [
                {
                    "name": user 1 name,
                    "id": user id,
                    "color": hex color of user,
                    "icon": icon url,
                    "identifier": user identifier
                },
                {
                    "name": user 2 name,
                    "id": user id,
                    "color": hex color of user,
                    "icon": icon url,
                    "identifier": user identifier
                } ...
            ],
            "roles": 
            [
                {
                    "name": role 1 name,
                    "id": role id ,
                    "color": hex color of role,
                },
                {
                    "name": role 2 name,
                    "id": role id ,
                    "color": hex color of role,
                } ...
            ],
            "everyone": if everyone is a dj (true / false)
        }
    },
    "channel": {
        "color": hex value of the embed color,
        "url": url for the embed image,
        "channel": 
        {
            "name": channel name,
            "id": channel id,
            "voice": true / false,
            "text": true / false
        } or null if no channel exists,
        "playlists": if you can edit playlists on the server (true / false),
        "command": 
        {
            "name": command channel name,
            "id": command channel id,
            "voice": true / false,
            "text": true / false
        } or null if no command channel exists,
    }
}

If you want to find a member by name:

GET /guild/ guild_id /named_member?name= name of the user you want to find
{
    [
        {
            "name": user 1 name,
            "id": user id,
            "color": hex color of user,
            "icon": icon url,
            "identifier": user identifier
        },
        {
            "name": user 2 name,
            "id": user id,
            "color": hex color of user,
            "icon": icon url,
            "identifier": user identifier
        } ...
    ]
}

To find a named role:

GET /guild/ guild_id /named_role?name= name of the user you want to find
{
    [
        {
            "name": role 1 name,
            "id": role id ,
            "color": hex color of role,
        },
        {
            "name": role 2 name,
            "id": role id ,
            "color": hex color of role,
        } ...
    ]
}

If you want to change some settings:

POST /guild/ guild_id /settings

To change a setting create a post body in the same scheme as the settings body from GET /settings and change a value, as an example (this will enable the blacklist and change the search engine to sp):

{
    "blacklist": {
        "enabled": true
    },
    "player": {
        "search": sp    
    }
}

The respone will be the full settings response

You can also reset the settings to the default value:

POST /guild/ guild_id /reset

Also returns the full settings response

Tracks#

Search for a specific track:

GET /tracks/search?query= the query to search for (same as the meta play command, therefore also supports source prefixes)

the usual response is different, if the prefix was pl, as it then returns a list of playlists:

{
    "type": "tracks",
    "tracks": [
        {
            "title": track 1 title,
            "author": track author,
            "url": track url,
            "identifier": track identifier,
            "thumbnail": track thumbnail url,
            "platform": track platform,
            "stream": true / false,
            "length": track length in ms,
            "favorite": true / false
        }, 
        {
            "title": track 2 title,
            "author": track author,
            "url": track url,
            "identifier": track identifier,
            "thumbnail": track thumbnail url,
            "platform": track platform,
            "stream": true / false,
            "length": track length in ms,
            "favorite": true / false
        } ...
    ]
}

or

{
    "type": "playlists",
    "playlists": [
        {
            "title": playlist 1 name,
            "author": playlist author,
            "image": playlist image url,
            "url": playlist url,
            "length": tracks in the playlist
        },
        {
            "title": playlist 1 name,
            "author": playlist author,
            "image": playlist image url,
            "url": playlist url,
            "length": tracks in the playlist
        }...
    ]
}

Get the track currently being played:

GET /tracks/current
{
    "title": track title,
    "author": track author,
    "url": track url,
    "identifier": track identifier,
    "thumbnail": track thumbnail url,
    "platform": track platform,
    "stream": true / false,
    "length": track length in ms,
    "favorite": true / false
}

A list of the tracks in the queue, limited to 100 per request:

GET /tracks/queue?indexes= a list of indexes like: 1,3,6,14 or ?start= start index &end= end index, for example start=50 end=100 gets the tracks from 50-100
{
    "tracks": [
        {
            "title": track 1 title,
            "author": track author,
            "url": track url,
            "identifier": track identifier,
            "thumbnail": track thumbnail url,
            "platform": track platform,
            "stream": true / false,
            "length": track length in ms,
            "favorite": true / false
        }, 
        {
            "title": track 2 title,
            "author": track author,
            "url": track url,
            "identifier": track identifier,
            "thumbnail": track thumbnail url,
            "platform": track platform,
            "stream": true / false,
            "length": track length in ms,
            "favorite": true / false
        } ...
    ],
    "length": how many tracks actually exist in the queue,
    "indexes": indexes of the requested tracks mathing the tracks array
}

To add a track request:

POST /tracks/add?query= query for the track to add (same as the meta play command, therefore also supports source prefixes)

the usual response is different, if the added track was a playlist, as it then returns a playlist as respond:

{
    "type": "tracks",
    "tracks": [
        {
            "title": track 1 title,
            "author": track author,
            "url": track url,
            "identifier": track identifier,
            "thumbnail": track thumbnail url,
            "platform": track platform,
            "stream": true / false,
            "length": track length in ms,
            "favorite": true / false
        }, 
        {
            "title": track 2 title,
            "author": track author,
            "url": track url,
            "identifier": track identifier,
            "thumbnail": track thumbnail url,
            "platform": track platform,
            "stream": true / false,
            "length": track length in ms,
            "favorite": true / false
        } ...
    ]
}

or

{
    "type": "playlist",
    "playlist": {     
        "title": playlist name,
        "author": playlist author,
        "image": playlist image url,
        "url": playlist url,
        "length": tracks in the playlist,
    }
    "tracks": [
        {
            "title": track 1 title,
            "author": track author,
            "url": track url,
            "identifier": track identifier,
            "thumbnail": track thumbnail url,
            "platform": track platform,
            "stream": true / false,
            "length": track length in ms,
            "favorite": true / false
        }, 
        {
            "title": track 2 title,
            "author": track author,
            "url": track url,
            "identifier": track identifier,
            "thumbnail": track thumbnail url,
            "platform": track platform,
            "stream": true / false,
            "length": track length in ms,
            "favorite": true / false
        } ...
    ]
}

Functions#

Gets the current settings of the player:

GET /functions/player
{
    "paused": true / false,
    "position": position in ms,
    "shuffle": true / false,
    "repeat": true / false,
    "repeat_song": true / false,
    "volume": volume,
    "equalizer": a list of the equalizer with 15 bands [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
}

Move a track:

POST /functions/move_track

The body should contain: { "index": The index of the track, which should be moved "position": The new position of the track }

returns true if everything was specified correct

Remove a track:

POST /functions/remove_track

The body should contain: { "index": The index of the track, which should be removed }

returns true if everything was specified correct

Skip a track:

POST /functions/skip
returns true if skipped

Change equalizer:

POST /functions/equalizer

The body should contain: [A list of 15 gains between -0.25 to 2]

returns a list of the equalizer with 15 bands

Go to previous track:

POST /functions/previous
returns true if previous

Set repeat:

POST /functions/repeat

The body should contain: true / false

returns true if repeat enabled, false if disabled

Set repeat track:

POST /functions/repeat_track

The body should contain: true / false

returns true if repeat track enabled, false if disabled

Set shuffle:

POST /functions/shuffle

The body should contain: true / false

returns true if shuffle enabled, false if disabled

Set volume:

POST /functions/volume

The body should contain: volume between 0 and volume limit

returns new volume

Stop the player:

POST /functions/stop
returns true

Eject the player:

POST /functions/eject
returns true

Pause the track:

POST /functions/paused

The body should contain: true / false

returns true if everything was specified correct

Seek the track:

POST /functions/seek

The body should contain: the position to seek for in ms

returns new position

Toggle track as favorite:

POST /functions/favorite

The body should contain: url of track to be toggled as favorite

returns:
{
    "title": track title,
    "author": track author,
    "url": track url,
    "identifier": track identifier,
    "thumbnail": track thumbnail url,
    "platform": track platform,
    "stream": true / false,
    "length": track length in ms,
    "favorite": true / false
}

Save the queue:

POST /functions/save
{
    "name": name,
    "type": meta,
    "id": playlist id,
    "image": "",
    "author": Discord user name,
    "key": playlist key
}

Playlists#

Playlist#

ServerSideEvents#