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
}