Protocol Details

The following definitions represent known endpoints relating to Google Music. They are organized by the client that uses them.

The names of these classes are semantic, and may not match their actual endpoint.

Most of the time, endusers will want to use one of the Client Interfaces. However, any of the definitions listed here can be called by using the _make_call member of a Client and providing the parameters needed by dynamic_* functions.

It’s tough to generate the exact schema of every call in a readable fashion, so this information is left out. If you need exact specifications, look at the code - or submit a pull request to generate the docs =)

Web Client

Calls made by the web client.

class gmusicapi.protocol.webclient.AddToPlaylist

Adds songs to a playlist.

static dynamic_data(playlist_id, song_ids)
Parameters:
  • playlist_id – id of the playlist to add to.
  • song_ids – a list of song ids
static_method = 'POST'
static_url = 'https://play.google.com/music/services/addtoplaylist'
class gmusicapi.protocol.webclient.ChangePlaylistOrder

Reorder existing tracks in a playlist.

static dynamic_data(playlist_id, song_ids_moving, entry_ids_moving, after_entry_id=None, before_entry_id=None)
Parameters:
  • playlist_id – id of the playlist getting reordered.
  • song_ids_moving – a list of consecutive song ids. Matches entry_ids_moving.
  • entry_ids_moving – a list of consecutive entry ids to move. Matches song_ids_moving.
  • after_entry_id – the entry id to place these songs after. Default first position.
  • before_entry_id – the entry id to place these songs before. Default last position.
static_method = 'POST'
static_url = 'https://play.google.com/music/services/changeplaylistorder'
class gmusicapi.protocol.webclient.ChangeSongMetadata

Edit the metadata of songs.

static dynamic_data(songs, session_id='')
Parameters:songs – a list of dicts {'id': '...', 'albumArtUrl': '...'}
static_method = 'POST'
static_params = {'format': 'jsarray'}
static_url = 'https://play.google.com/music/services/modifytracks'
class gmusicapi.protocol.webclient.CreatePlaylist

Adds songs to a playlist.

static dynamic_data(name, description, public, session_id='')
static_method = 'POST'
static_params = {'format': 'jsarray'}
static_url = 'https://play.google.com/music/services/createplaylist'
class gmusicapi.protocol.webclient.DeauthDevice

Deauthorize a device from GetSettings.

static dynamic_data(device_id, session_id)
static_method = 'POST'
static_url = 'https://play.google.com/music/services/modifysettings'
class gmusicapi.protocol.webclient.DeletePlaylist

Delete a playlist.

static dynamic_data(playlist_id)
Parameters:playlist_id – id of the playlist to delete.
static_method = 'POST'
static_url = 'https://play.google.com/music/services/deleteplaylist'
class gmusicapi.protocol.webclient.DeleteSongs

Delete a song from the entire library or a single playlist.

static dynamic_data(song_ids, playlist_id='all', entry_ids=None)
Parameters:
  • song_ids – a list of song ids.
  • playlist_id – playlist id to delete from, or ‘all’ for deleting from library.
  • entry_ids – when deleting from playlists, corresponding list of entry ids.
static_method = 'POST'
static_url = 'https://play.google.com/music/services/deletesong'
class gmusicapi.protocol.webclient.GetDownloadInfo

Get download links and counts for songs.

static dynamic_data(song_ids)
Param:(list) song_ids
static_method = 'POST'
static_url = 'https://play.google.com/music/services/multidownload'
class gmusicapi.protocol.webclient.GetSettings

Get data that populates the settings tab: labs and devices.

static dynamic_data(session_id)
Param:session_id
static_method = 'POST'
static_url = 'https://play.google.com/music/services/loadsettings'
class gmusicapi.protocol.webclient.GetSharedPlaylist

Get the contents and metadata for a shared playlist.

static dynamic_data(session_id, share_token)
classmethod parse_response(response)
static_method = 'POST'
static_params = {'format': 'jsarray'}
static_url = 'https://play.google.com/music/services/loadsharedplaylist'
class gmusicapi.protocol.webclient.GetStreamUrl

Used to request a streaming link of a track.

static dynamic_params(song_id)
required_auth = AuthTypes(xt=False, sso=True, oauth=False)
static_method = 'GET'
static_url = 'https://play.google.com/music/play'
class gmusicapi.protocol.webclient.Init

Called one time per session, immediately after login.

This performs one-time setup: it gathers the cookies we need (specifically xt), and Google uses it to create the webclient DOM.

Note the use of the HEAD verb. Google uses GET, but we don’t need the large response containing Google’s webui.

classmethod check_success(response, msg)
static parse_response(response)
required_auth = AuthTypes(xt=False, sso=True, oauth=False)
static_method = 'HEAD'
static_url = 'https://play.google.com/music/listen'
class gmusicapi.protocol.webclient.ReportBadSongMatch

Request to signal the uploader to reupload a matched track.

static dynamic_data(song_ids)
static_method = 'POST'
static_params = {'format': 'jsarray'}
static_url = 'https://play.google.com/music/services/fixsongmatch'
class gmusicapi.protocol.webclient.UploadImage

Upload an image for use as album art.

static dynamic_files(image_filepath)
Parameters:image_filepath – path to an image
static_method = 'POST'
static_params = {'u': 0, 'zx': ''}
static_url = 'https://play.google.com/music/services/imageupload'

Music Manager

Calls made by the Music Manager (related to uploading).

class gmusicapi.protocol.musicmanager.AuthenticateUploader

Sent to auth, reauth, or register our upload client.

classmethod check_success(response, msg)
classmethod dynamic_data(uploader_id, uploader_friendly_name)
Parameters:
  • uploader_id – MM uses host MAC address
  • uploader_friendly_name – MM uses hostname
static_url = 'https://android.clients.google.com/upsj/upauth'
static_verify = False
class gmusicapi.protocol.musicmanager.CancelUploadJobs

This call will cancel any outstanding upload jobs (ie from GetJobs). The Music Manager only calls it when the user changes the location of their local collection.

It doesn’t actually return anything useful.

static dynamic_data(uploader_id)
Parameters:uploader_id – id
static_method = 'POST'
static_url = 'https://android.clients.google.com/upsj/deleteuploadrequested'
static_verify = False
class gmusicapi.protocol.musicmanager.DownloadTrack

Given a url, retrieve a track. Unlike the Webclient, this requires authentication.

The entire Requests.Response is returned.

static dynamic_url(url)
Parameters:url – result of a call to GetDownloadLink
classmethod parse_response(response)
static_method = 'GET'

Get a url where a track can be downloaded.

Auth is not needed to retrieve the resulting url.

static dynamic_headers(sid, client_id)
static dynamic_params(sid, client_id)
classmethod parse_response(response)
static_headers = {}
static_method = 'GET'
static_params = {'version': 2}
static_url = 'https://music.google.com/music/export'
class gmusicapi.protocol.musicmanager.GetUploadJobs
classmethod check_success(response, msg)
classmethod dynamic_data(uploader_id)
Parameters:uploader_id – MM uses host MAC address
static_params = {'version': 1}
static_url = 'https://android.clients.google.com/upsj/getjobs'
static_verify = False
class gmusicapi.protocol.musicmanager.GetUploadSession

Called when we want to upload; the server returns the url to use. This is a json call, and doesn’t share much with the other calls.

static dynamic_data(uploader_id, num_already_uploaded, track, filepath, server_id, do_not_rematch=False)

track is a locker_pb2.Track, and the server_id is from a metadata upload.

classmethod parse_response(response)
static process_session(res)

Return (got_session, error_details). error_details is (should_retry, reason, error_code) or None if got_session.

static_method = 'POST'
static_url = 'https://uploadsj.clients.google.com/uploadsj/rupio'
class gmusicapi.protocol.musicmanager.ListTracks

List all tracks. Returns a subset of all available metadata. Can optionally filter for only free/purchased tracks.

classmethod check_success(response, msg)
static dynamic_data(client_id, cont_token=None, export_type=1, updated_min=0)

Works similarly to the webclient method. Chunks are up to 1000 tracks.

Parameters:
  • client_id – an authorized uploader_id
  • cont_token – (optional) token to get the next library chunk.
  • export_type – 1=’ALL’, 2=’PURCHASED_AND_PROMOTIONAL’
  • updated_min – likely a timestamp; never seen an example of this != 0
static dynamic_headers(client_id, *args, **kwargs)
res_msg_type

alias of GetTracksToExportResponse

static_method = 'POST'
static_url = 'https://music.google.com/music/exportids'
class gmusicapi.protocol.musicmanager.OAuthInfo

OAuthInfo(client_id, client_secret, scope, redirect)

client_id

Alias for field number 0

client_secret

Alias for field number 1

redirect

Alias for field number 3

scope

Alias for field number 2

class gmusicapi.protocol.musicmanager.ProvideSample

Give the server a scan and match sample. The sample is a 128k mp3 slice of the file, usually 15 seconds long.

static dynamic_data(filepath, server_challenge, track, uploader_id, mock_sample=None)

Raise IOError on transcoding problems, or ValueError for invalid input.

Parameters:mock_sample – if provided, will be sent in place of a proper sample
static_method = 'POST'
static_params = {'version': 1}
static_url = 'https://android.clients.google.com/upsj/sample'
static_verify = False
class gmusicapi.protocol.musicmanager.UpdateUploadState

Notify the server that we will be starting/stopping/pausing our upload.

I believe this is used for the webclient ‘currently uploading’ widget, but that might also be the current_uploading information.

static dynamic_data(to_state, uploader_id)

Raise ValueError on problems.

Parameters:to_state – one of ‘start’, ‘paused’, or ‘stopped’
static_method = 'POST'
static_params = {'version': 1}
static_url = 'https://android.clients.google.com/upsj/sample'
static_verify = False
class gmusicapi.protocol.musicmanager.UploadFile

Called after getting a session to actually upload a file.

static dynamic_data(session_url, content_type, audio)
static dynamic_headers(session_url, content_type, audio)
static dynamic_url(session_url, content_type, audio)
classmethod parse_response(response)
static_method = 'PUT'
class gmusicapi.protocol.musicmanager.UploadMetadata
count_fields = {'tracknumber': ('track_number', 'total_track_count'), 'discnumber': ('disc_number', 'total_disc_count')}
classmethod dynamic_data(tracks, uploader_id, do_not_rematch=False)
Parameters:
  • tracks – list of filled locker_pb2.Track
  • uploader_id
  • do_not_rematch – seems to be ignored
field_map = {'albumartist': 'album_artist', 'bpm': 'beats_per_minute'}
classmethod fill_track_info(filepath)

Given the path and contents of a track, return a filled locker_pb2.Track. On problems, raise ValueError.

static get_track_clientid(filepath)
shared_fields = ('album', 'artist', 'composer', 'genre')
static_params = {'version': 1}
static_url = 'https://android.clients.google.com/upsj/metadata'
static_verify = False
gmusicapi.protocol.musicmanager.credentials_from_refresh_token(token)
gmusicapi.protocol.musicmanager.pb(f)

Decorator to serialize a protobuf message.