V0.2.0 Documentation
-
- Authorization
- User
- JamSession
- Create a new JamSession
- Get the information of the JamSession joined by the user
- Get the playback of the JamSession joined by the user
- Join an existing JamSession
- Leave the JamSession currently joined by the user
- Set playback of the JamSession joined by the user
- Set the information of the JamSession joined by the user
- Get the members of the JamSession joined by the user
- Set the members of the JamSession joined by the user
- Queue
- Add a collection to the queue of the JamSession joined by the user
- Delete a song in the queue of the JamSession joined by the user
- Get the queue of the JamSession joined by the user
- Vote for a song in the queue of the JamSession joined by the user
- Get the played song history of the JamSession joined by the user
- Export the queue to a Playlist
- Spotify
JamFactory is an application that provides the necessary API to start a JamSession.
A JamSession is a private party with one host who sets it up and many participants who can join in.
Your friends or party guests can vote for the songs they like and want to hear, and the song with the most votes will be played next. The host can choose a Spotify playback device to play the music on.
The host of a JamSession must have a Spotify Premium account, guests can join the JamSession without a Spotify account.
JamFactory uses basic user management to remember and recognize different users from each other.
A Session is used to identify calls to the API using a session cookie. Each session contains a session ID and an optional identifier that is used to associate the session with a user.
A User can be either a guest, identified only by the session, or an authorized Spotify user. Users are stored in the Redis database. For authorized users, the email address is used as an identifier. If the same user authorizes on different devices with the same Spotify account, the session will point to the same user. Guest users are created for users who are not authorized by spotify. Each user has a display name. For Spotify users, the Spotify display name is used. For guest users, a random 5-character string with the prefix "Guest" is used. Guest users are only created and stored in the database when they join a JamSession.
The following User types can occur
| type | description |
|---|---|
New |
No User exists in the database. The user needs to join a JamSession or authorize himself |
Guest |
The User is not authorized but joined a JamSession as a Guest |
Spotify |
The User has authorized himself using Spotify |
Based on the User type the identifier generation differs
| type | description |
|---|---|
New |
No Identifier is generated |
Guest |
The Identifier is generated using the session id |
Spotify |
The Identifier is generated using the email address of the spotify account id |
A Member is a user who has joined and received certain rights for a specific JamSession. The rights are not global and apply only to the joined JamSession. The JamSession Member object contains only an identifier that points to the user, and is stored only within the JamSession itself. Currently, a user can only be a member of one JamSession at a time.
The following Member Rights are currently available. Each endpoint lists which rights are required to access it.
| type | description |
|---|---|
Guest |
The Member joined an ongoing JamSession as a Guest. |
Host |
The Member the Host of a JamSession. |
To decide which song will be played next in an ongoing JamSession, all guests, and the host, can vote for songs of their choice. Every JamSession has a queue of songs, which is sorted by the number of votes per song. Which song will be played next, is based on the number of votes a song has. The more votes a song has, the higher the song is in the queue. If it can't be clearly determined by votes, where the song should be placed in the queue, the order of the queue is dictated by the age of the songs added. A song which has been longer in the queue will be placed higher than a more recently added song. When the currently played song ends, the song which is highest in the queue will be played next. When a user votes for a song, which currently is not in the queue, the song will automatically be added to the queue with one initial vote of the user that suggested the song. If the song has already previously been added to the queue, that song's votes will be increased by one vote. A song can only exist once in a queue.
A vote can be retracted from a song in the queue, by voting again. Only the user's own vote can be taken away. When a song reaches zero votes, it will automatically be deleted from the queue.
To keep track of which user voted for which song, each vote has a unique identifier based on the user identifier. See What is a User.
When a new JamSession is created, the queue will be empty. To get the jam going from the getgo, the host can decide to add a collection to the queue. The songs in the collection are voted into the queue with one virtual vote. Although adding the collection to the queue, the host can still vote independently for each song of the collection.
The virtual votes are added with a date in the future, meaning songs with only virtual votes will be added to the bottom of the queue, because "real" votes have a higher priority. The songs with only virtual votes will serve as a fallback, as soon as there are no more songs with user votes left, so the jam never stops.
To keep the jam going, each JamSession has its own conductor who will keep track of the current events. The conductor will, for instance, check if the current song has ended, and if the next song should start. He also keeps track of the current playback of the session.
It is possible that the host does not want the conductor to interfere with the playback, even if the JamSession is still ongoing. The JamSession state will determine if the conductor has the right to control the Spotify playback.
The following event will change the JamSession state:
| event | change to |
|---|---|
| User creates a JamSession | inactive |
| User sets the JamSession to active | active |
| User sets the JamSession to inactive | inactive |
| User pauses playback through the JamFactory App | no change |
| User resumes playback through the JamFactory App | no change |
| User pauses playback through Spotify | no change |
| User resumes playback through Spotify | no change |
| User starts playback through Spotify | inactive |
| type | value type | description |
|---|---|---|
spotifyTrackFull |
Spotify Track Object | The Spotify Track |
votes |
number | Number of Votes for the Queue Song |
voted |
boolean | True if the request initiator Voted for the Queue Song. Always false for WebSocket Messages |
| type | value type | description |
|---|---|---|
display_name |
string | The Display Name of the User |
rights |
[]string | The IP Address of the User is used as an identifier |
Description
Get the user's current authorization status.
Endpoint:
Method: GET
URL: jamfactory.app/api/v1/auth/currentRequest Body (Empty):
Response Body (JSON):
| key | value type | value description |
|---|---|---|
user |
string | Current User Type. See available User Types |
label |
string | JamLabel of the currently joined JamSession for the User. Empty if the User has not joined a JamSession. |
authorized |
boolean | Current Spotify authorization status. True if the User completed the Spotify authorization process. |
{
"user": "Host",
"label": "GF7DZ",
"authorized": true
}Description
Logout the current user. This will remove any session data of the user and remove the Spotify authorization. The JamSession will also be deleted if the user was its host. It is recommended to first leave any joined JamSession before logging out.
Endpoint:
Method: GET
URL: jamfactory.app/api/v1/auth/logoutRequest Body (Empty):
Response Body (JSON):
| key | value type | value description |
|---|---|---|
success |
boolean | Feedback if the logout process was successful. |
{
"success": true
}Description
Start the Spotify authorization process for the current user. Uses the Authorization Code Flow from Spotify. Requires the user to have a Spotify premium account.
Endpoint:
Method: GET
URL: jamfactory.app/api/v1/auth/loginRequest Body (Empty):
Response Body (JSON):
| key | value type | value description |
|---|---|---|
url |
string | The Url to the Spotify Account Service for authorization. See Authorization Code Flow |
{
"url": "https://accounts.spotify.com/authorize"
}Description*
Get the current user information and authorization status
Endpoint:
Method: GET
URL: jamfactory.app/api/v1/meRequest Body (Empty):
Response Body (JSON):
| key | value type | value description |
|---|---|---|
identifier |
string | The unique identifier for the User. When the user type is Empty, the field contains an empty string |
display_name |
string | The display name of the User. When the user type is Empty, the field contains an empty string |
type |
string | The user type of the User. See User Types |
joined_label |
string | The JamLabel of the JamSession the user has joined. If the user is not a member of any JamSession the field will contain an empty string |
spotify_authorized |
boolean | Current Spotify authorization status. true if the User has a valid Spotify authorization |
{
"identifier": "abcdefg123456",
"display_name": "ABBA Fan",
"type": "Spotify",
"joined_label": "E5Z6U",
"spotify_authorized": true
}Description
Set the current user information. Requires to not be of type Empty. See User Types
Endpoint:
Method: PUT
URL: jamfactory.app/api/v1/meRequest Body (JSON):
| key | value type | value description |
|---|---|---|
display_name |
string | The display name of the User. |
{
"display_name": "ABBA Fan"
}Response Body (JSON):
| key | value type | value description |
|---|---|---|
identifier |
string | The unique identifier for the User. When the user type is Empty, the field contains an empty string |
display_name |
string | The display name of the User. When the user type is Empty, the field contains an empty string |
type |
string | The user type of the User. See User Details |
joined_label |
string | The JamLabel of the JamSession the user has joined. If the user is not a member of any JamSession the field will contain an empty string |
spotify_authorized |
boolean | Current Spotify authorization status. true if the User has a valid Spotify authorization |
{
"identifier": "abcdefg123456",
"display_name": "ABBA Fan",
"type": "Spotify",
"joined_label": "E5Z6U",
"spotify_authorized": true
}Description
Delete the current user information. This will delete the user object from the database. Important: The user will be deleted, but creating a new user probably results in the same identifier to prevent vote cheating. See User Identifier Generation.
Endpoint:
Method: DELETE
URL: jamfactory.app/api/v1/meRequest Body (Empty):
Response Body (JSON):
| key | value type | value description |
|---|---|---|
success |
boolean | Result of the operation. |
{
"success": true
}Description
Create a new JamSession. Requires the user to be authorized by Spotify. The user will join the JamSession as the host. The default password for a newly created JamSession is an empty string. Endpoint:
Method: GET
URL: jamfactory.app/api/v1/jam/createRequest Body (Empty):
Response Body (JSON):
| key | value type | value description |
|---|---|---|
label |
string | The JamLabel of the created JamSession |
{
"label": "HG5FZ"
}Description
Get the information of the JamSession currently joined by the user. Requires the user to have joined a JamSession.
Endpoint:
Method: GET
URL: jamfactory.app/api/v1/jamRequest Body (Empty):
Response Body (JSON):
| key | value type | value description |
|---|---|---|
label |
string | JamLabel of the currently joined JamSession |
name |
string | Name of the currently joined JamSession |
active |
bool | State of the currently joined JamSession. See JamSession State |
{
"label": "TPMU4",
"name": "Joe's Birthday Party",
"active": true
}Description
Get the playback of the JamSession currently joined by the user. Requires the user to have joined a JamSession.
Endpoint:
Method: GET
URL: jamfactory.app/api/v1/jam/playbackRequest Body (Empty):
Response Body (JSON):
| key | value type | value description |
|---|---|---|
playback |
Spotify Playback Object | Playback state |
device_id |
string | Device ID of the currently selected playback device. |
{
"playback": "<Spotify Playback Object>",
"device_id": "abc123456"
}Description
Join an existing JamSession. The user will join the JamSession as a guest.
The default password for a JamSession is an empty string """.
Endpoint:
Method: PUT
URL: jamfactory.app/api/v1/jam/joinRequest Body (JSON):
| key | value type | value description |
|---|---|---|
label |
string | The JamLabel of the JamSession the User wants to join. |
password |
string | The Password of the JamSession the User wants to join. |
{
"label": "KWXBZ",
"password": "Birthday"
}Response Body (JSON):
| key | value type | value description |
|---|---|---|
label |
string | The JamLabel of the joined JamSession. |
{
"label": "KWXBZ"
}Description
Leave the JamSession currently joined by the user. If the user is the host of the JamSession, the JamSession will be deleted. Also returns a success confirmation if the user isn't a member of any JamSession.
Endpoint:
Method: GET
URL: jamfactory.app/api/v1/jam/leaveRequest Body (Empty):
Response Body (JSON):
| key | value type | value description |
|---|---|---|
success |
boolean | Result of the operation. |
{
"success": true
}Description
Set the playback of the JamSession currently joined by the user. Requires the user to be the host of the JamSession.
Endpoint:
Method: PUT
URL: jamfactory.app/api/v1/jam/playbackResponse Body (JSON):
| key | value type | value description |
|---|---|---|
device_id |
string optional | Device ID of the playback device. |
playing |
boolean optional | Playback state. True= Play False = Pause |
volume |
number optional | Playback volume in percent 0 - 100 |
{
"device_id": "abc123456",
"playing": false,
"volume": 60
}Response Body (JSON):
| key | value type | value description |
|---|---|---|
playback |
Spotify Playback Object | Playback state |
device_id |
string | Device ID of the currently selected playback device. |
{
"playback": "<Spotify Playback Object>",
"device_id": "abc123456"
}Description
Get the information of the JamSession currently joined by the user. Requires the user to be the host of the JamSession. The information is only changed, if the key is included in the request body.
Endpoint:
Method: PUT
URL: jamfactory.app/api/v1/jamRequest Body (JSON):
| key | value type | value description |
|---|---|---|
name |
string optional | Name of the JamSession currently joined by the user. |
active |
boolean optional | State of the JamSession currently joined by the user. See JamSession State. |
password |
string optional | The Password of the JamSession. If a empty string is send, the current password will get removed. |
{
"name": "Joe's Birthday Party",
"active": true,
"password": "Birthday"
}Response Body (JSON):
| key | value type | value description |
|---|---|---|
label |
string | JamLabel of the currently joined JamSession |
name |
string | Name of the currently joined JamSession |
active |
string | State of the currently joined JamSession. See JamSession State |
{
"label": "TPMU4",
"name": "Joe's Birthday Party",
"active": true
}Description
Get members and their rights of the JamSession currently joined by the user. Requires the user to have joined a JamSession.
Endpoint:
Method: GET
URL: jamfactory.app/api/v1/jam/membersRequest Body (Empty):
Response Body (JSON):
| key | value type | value description |
|---|---|---|
members |
JamSession Members | Array of Members of the current JamSession |
{
"members": [
{
"display_name": "Joe",
"identifier": "abcdefg123456",
"rights": [
"Host",
"Guest"
]
},
{
"display_name": "Guest A5E1D",
"identifier": "123456abcdefg",
"rights": [
"Guest"
]
}
]
}Description
Set the information of the JamSession currently joined by the user. Requires the user to be the Host of a JamSession. Important: Changing the display name in the request does not have any result
Endpoint:
Method: PUT
URL: jamfactory.app/api/v1/jam/membersRequest Body (Empty):
| key | value type | value description |
|---|---|---|
members |
JamSession Members | Array of Members of the current JamSession |
{
"members": [
{
"display_name": "Joe",
"identifier": "abcdefg123456",
"rights": [
"Host",
"Guest"
]
},
{
"display_name": "Guest A5E1D",
"identifier": "123456abcdefg",
"rights": [
"Guest"
]
}
]
}Response Body (JSON):
| key | value type | value description |
|---|---|---|
members |
JamSession Members | Array of Members of the current JamSession |
{
"members": [
{
"display_name": "Joe",
"identifier": "abcdefg123456",
"rights": [
"Host",
"Guest"
]
},
{
"display_name": "Guest A5E1D",
"identifier": "123456abcdefg",
"rights": [
"Guest"
]
}
]
}Description
Directly play a song for the JamSession joined by the user without corrupting the queue or changing the state.
A skip functionality can be implemented when setting the key delete to true and playing the song on top of the queue.
Requires the user to be the host of a JamSession.
Endpoint:
Method: PUT
URL: jamfactory.app/api/v1/jam/playRequest Body (JSON):
| key | value type | value description |
|---|---|---|
track |
string | Spotify ID of the track. See Spotify Track Object |
remove |
boolean | Remove the song, if present, from the current queue |
{
"track": "2374M0fQpWi3dLnB54qaLX",
"remove": true
}Response Body (JSON):
| key | value type | value description |
|---|---|---|
success |
boolean | Result of the operation. |
{
"success": true
}Description
Add a Spotify collection (playlist or album) to the current queue of the JamSession joined by the user. This can be used to add fallback music to a JamSession. The songs in the collection are voted in the queue with a virtual vote. The user adding the collection can still vote for the added songs. Note that the virtual votes, for the songs in the playlist, are added with a date in the future. A real vote of a user will overrule the virtual vote and therefore be listed higher up in the queue. For more details see How voting works.
Requires the user to be the host of the JamSession.
Endpoint:
Method: PUT
URL: jamfactory.app/api/v1/queue/collectionRequest Body (JSON):
| key | value type | value description |
|---|---|---|
collection |
string required | Spotify ID of the collection |
type |
string required | Type of the collection. playlist for a playlist album for an album |
{
"collection": "3AGOiaoRXMSjswCLtuNqv5",
"type": "album"
}Response Body (JSON):
| key | value type | value description |
|---|---|---|
queue |
array | Array of the songs in the current queue. See Queue Song. The queue song objects are personalized to the user requesting the queue. |
{
"queue": "[]<Queue Song Object>"
}Description
Delete a song in the queue of the JamSession joined by the user. Only songs which are currently in the queue can be deleted. This deletes all existing votes for a song, but does not prevent a new vote for that song.
Requires the user to be the host of the JamSession.
Endpoint:
Method: DELETE
URL: jamfactory.app/api/v1/queue/deleteRequest Body (JSON):
| key | value type | value description |
|---|---|---|
track |
string required | Spotify ID of the track which should be deleted. See Spotify Track Object |
{
"track": "2374M0fQpWi3dLnB54qaLX"
}Response Body (JSON):
| key | value type | value description |
|---|---|---|
queue |
array | Array of the songs in the current queue. See Queue Song. The queue song objects are personalized to the user requesting the queue. |
{
"queue": "[]<Queue Song Object>"
}Description
Returns the queue of the JamSession joined by the user. Don't query this endpoint on a regular basis. To get updates on changes to the queue use the provided socket. See Socket Reference.
Requires the user to have joined the JamSession.
Endpoint:
Method: GET
URL: jamfactory.app/api/v1/queueRequest Body (Empty):
Response Body (JSON):
| key | value type | value description |
|---|---|---|
tracks |
array | Array of the songs in the current queue. See Queue Song. The queue song objects are personalized to the user requesting the queue. |
{
"tracks": "[]<Queue Song Object>"
}Description
Add or remove a vote from the user to a song in the JamSession joined by the user. See How voting works for a more detailed description on how voting works.
Requires the user to have joined the JamSession.
Endpoint:
Method: PUT
URL: jamfactory.app/api/v1/queue/voteRequest Body (JSON):
| key | value type | value description |
|---|---|---|
track |
string required | Spotify ID of the track. See Spotify Track Object |
{
"track": "2374M0fQpWi3dLnB54qaLX"
}Response Body (JSON):
| key | value type | value description |
|---|---|---|
queue |
array | Array of the songs in the current queue. See Queue Song. The queue song objects are personalized to the user requesting the queue. |
{
"queue": "[]<Queue Song Object>"
}Description
Returns the history of the queue including all played songs of the JamSession joined by the user. Requires the user to have joined the JamSession.
Endpoint:
Method: GET
URL: jamfactory.app/api/v1/queue/historyRequest Body (Empty):
Response Body (JSON):
| key | value type | value description |
|---|---|---|
history |
array | Array of the played songs of the current queue. See Queue Song. The queue song objects are personalized to the user requesting the queue. |
{
"history": "[]<Queue Song Object>"
}Description
Creates a Playlist containing the history and/or the queued songs of the current queue of the JamSession joined by the user. Requires the user be the Host of a JamSession.
Endpoint:
Method: PUT
URL: jamfactory.app/api/v1/queue/exportRequest Body (JSON):
| key | value type | value description |
|---|---|---|
playlist_name |
string | The Spotify playlist name |
include_history |
boolean | Include the history of the queue |
include_queue |
boolean | Include the queued songs |
{
"playlist_name": "Songs of my birthday party",
"include_history": true,
"include_queue": false
}Response Body (JSON):
| key | value type | value description |
|---|---|---|
success |
boolean | Result of the operation. |
{
"success": true
}Description
Get information about the current available devices of the user. Requires the current user to be a JamSession host.
Endpoint:
Method: GET
URL: jamfactory.app/api/v1/spotify/devicesRequest Body (Empty):
Response Body (JSON):
| key | value type | value description |
|---|---|---|
devices |
array | Array of the available Spotify playback devices of the User. See Spotify Device Object |
{
"devices": "[]<Spotify Device Object>"
}Description
Get a list of all Spotify playlists owned or followed by the current user. Requires the current user to be a JamSession host.
Endpoint:
Method: GET
URL: jamfactory.app/api/v1/spotify/playlistsRequest Body (Empty):
Response Body (JSON):
| key | value type | value description |
|---|---|---|
playlists |
Spotify Paging Object | Array of the users available Spotify playlists as Spotify Simplified Playlist Object wrapped in a Spotify Paging Object |
{
"playlists": "<Spotify Paging Object>"
}Description
Get Spotify catalog information about playlists and tracks that match a keyword string. Requires the current user to have joined the JamSession.
Endpoint:
Method: PUT
URL: jamfactory.app/api/v1/spotify/searchRequest Body (JSON):
| key | value type | value description |
|---|---|---|
text |
string required | Search text. All search texts are completed with a * for autofill. |
type |
string required | Type of the searched item. Available:track for Spotify tracks,playlist for Spotify playlists |
{
"text": "abba",
"type": "track"
}Response Body (JSON):
| key | value type | value description |
|---|---|---|
artists |
Spotify Paging Object | Spotify artists found with the submitted search term as Spotify Simplified Artists Object wrapped in a Spotify Paging Object |
albums |
Spotify Paging Object | Spotify albums found with the submitted search term as Spotify Simplified Album Object wrapped in a Spotify Paging Object |
playlists |
Spotify Paging Object | Spotify playlists found with the submitted search term as Spotify Simplified Playlist Object wrapped in a Spotify Paging Object |
tracks |
Spotify Paging Object | Spotify tracks found with the submitted search term as Spotify Simplified Track Object wrapped in a Spotify Paging Object |
{
"artists": "<Spotify Paging Object>",
"albums": "<Spotify Paging Object>",
"playlists": "<Spotify Paging Object>",
"tracks": "<Spotify Paging Object>"
}JamFactory provides Websockets to notify the user at certain events and regularly update the playback status.
When the user has joined a JamSession as a host or as a guest, he can connect to the corresponding Websocket created by the JamSession. The connection is automatically made to the correct Websocket, based on the session cookie. The client only needs to open or close the connection and listen for the events.
Websocket Endpoint: The endpoint where the websocket connection is available is:
ws://jamfactory.app/ws
A message provided by the websocket is formatted in JSON and has the following form
| key | value type | value description |
|---|---|---|
event |
string | Event type of the Message. See all available Websocket Events |
message |
JSON Object | The message corresponding to the event |
The setting of the JamSession changed.
Message (JSON):
| key | value type | value description |
|---|---|---|
label |
string | JamLabel of the JamSession currently joined by the user. |
name |
string | Name of the JamSession currently joined by the user. |
active |
boolean | State of the JamSession currently joined by the user. See JamSession State |
{
"label": "TPMU4",
"name": "Joe's Birthday Party",
"active": true
}The queue of the JamSession joined by the user has changed.
Message (JSON):
| key | value type | value description |
|---|---|---|
queue |
array | Array of the songs in the current queue. See Queue Song. The queue song objects are not personalized to the user requesting the queue. |
{
"queue": "[]<Queue Song Object>"
}The members of the JamSession changed.
Message (JSON):
| key | value type | value description |
|---|---|---|
members |
JamSession Members | Array of Members of the current JamSession. |
{
"members": [
{
"display_name": "Joe",
"identifier": "abcdefg123456",
"rights": [
"Host",
"Guest"
]
},
{
"display_name": "Guest A5E1D",
"identifier": "123456abcdefg",
"rights": [
"Guest"
]
}
]
}Update on the current playback state of the JamSession. This event is triggered approximately every second.
Message (JSON):
| key | value type | value description |
|---|---|---|
playback |
Spotify Playback Object | Playback state |
device_id |
string | Device ID of the currently selected playback device |
{
"playback": "<Spotify Playback Object>",
"device_id": "abc123456"
}The JamSession was or will be closed.
Message (String):
Reason why the JamSession was closed.
| Reason | Description |
|---|---|
host |
The host closed the JamSession. |
warning |
The JamSession will be closed due to inactivity shortly |
inactive |
The JamSession was closed due to inactivity. |