Webclient Interface

Webclient functionality is not tested nor well supported.
Use Mobileclient or Musicmanager if possible.

class gmusicapi.clients.Webclient(debug_logging=True, validate=True, verify_ssl=True)

Allows library management and streaming by posing as the music.google.com webclient.

Uploading is not supported by this client (use the Musicmanager to upload).

Any methods in this class that are duplicated by the Mobileclient are deprecated, and will generate a warning at runtime.

The following methods are not deprecated:

Setup and login

Webclient.__init__(debug_logging=True, validate=True, verify_ssl=True)
  • debug_logging

    each Client has a logger member. The logger is named gmusicapi.<client class><client number> and will propogate to the gmusicapi root logger.

    If this param is True, handlers will be configured to send this client’s debug log output to disk, with warnings and above printed to stderr. Appdirs user_log_dir is used by default. Users can run:

    from gmusicapi.utils import utils
    print utils.log_filepath

    to see the exact location on their system.

    If False, no handlers will be configured; users must create their own handlers.

    Completely ignoring logging is dangerous and not recommended. The Google Music protocol can change at any time; if something were to go wrong, the logs would be necessary for recovery.

  • validate

    if False, do not validate server responses against known schemas. This helps to catch protocol changes, but requires significant cpu work.

    This arg is stored as self.validate and can be safely modified at runtime.

  • verify_ssl – if False, exceptions will not be raised if there are problems verifying SSL certificates. Be wary of using this option; it’s almost always better to fix the machine’s SSL configuration than to ignore errors.
Webclient.login(email, password)

Authenticates the webclient. Returns True on success, False on failure.

  • email – eg 'test@gmail.com' or just 'test'.
  • password – the account’s password. This is not stored locally, and is sent securely over SSL. App-specific passwords are not supported on the webclient.

Users who don’t use two-factor auth will likely need to enable less secure login. If this is needed, a warning will be logged during login (which will print to stderr in the default logging configuration).


Forgets local authentication and cached properties in this Api instance. Returns True on success.

Song downloading and streaming


Returns a tuple: ('<url>', <download count>).

Parameters:song_id – a single song id.

url will be None if the download limit is exceeded.

GM allows 2 downloads per song. The download count may not always be accurate, and the 2 download limit seems to be loosely enforced.

This call alone does not count towards a download - the count is incremented when url is retrieved.

Webclient.get_stream_audio(song_id, use_range_header=None)

Returns a bytestring containing mp3 audio for this song.

  • song_id – a single song id
  • use_range_header

    in some cases, an HTTP range header can be used to save some bandwidth. However, there’s no guarantee that the server will respect it, meaning that the client may get back an unexpected response when using it.

    There are three possible values for this argument:
    • None: (default) send header; fix response locally on problems
    • True: send header; raise OSError on problems
    • False: do not send header

Returns a list of urls that point to a streamable version of this song.

If you just need the audio and are ok with gmusicapi doing the download, consider using get_stream_audio() instead. This abstracts away the differences between different kinds of tracks:

  • normal tracks return a single url
  • All Access tracks return multiple urls, which must be combined
Parameters:song_id – a single song id.

While acquiring the urls requires authentication, retreiving the contents does not.

However, there are limitations on how the stream urls can be used:

  • the urls expire after a minute
  • only one IP can be streaming music at once. Other attempts will get an http 403 with X-Rejected-Reason: ANOTHER_STREAM_BEING_PLAYED.

This is only intended for streaming. The streamed audio does not contain metadata. Use get_song_download_info() or Musicmanager.download_song to download files with metadata.


Equivalent to the ‘Fix Incorrect Match’ button, this requests re-uploading of songs. Returns the song_ids provided.

Parameters:song_ids – a list of song ids to report, or a single song id.

Note that if you uploaded a song through gmusicapi, it won’t be reuploaded automatically - this currently only works for songs uploaded with the Music Manager. See issue #89.

This should only be used on matched tracks (song['type'] == 6).

Song manipulation

Webclient.upload_album_art(song_ids, image_filepath)

Uploads an image and sets it as the album art for songs. Returns a url to the image on Google’s servers.

  • song_ids – a list of song ids, or a single song id.
  • image_filepath – filepath of the art to use. jpg and png are known to work.

This function will always upload the provided image, even if it’s already uploaded. If the art is already uploaded and set for another song, copy over the value of the 'albumArtUrl' key using Mobileclient.change_song_metadata() instead.


Deprecated: prefer Mobileclient.delete_songs().

Deletes songs from the entire library. Returns a list of deleted song ids.

Parameters:song_ids – a list of song ids, or a single song id.

Playlist manipulation

Webclient.create_playlist(name, description=None, public=False)

Creates a playlist and returns its id.

  • name – the name of the playlist.
  • description – (optional) the description of the playlist.
  • public – if True and the user has All Access, create a shared playlist.
Webclient.add_songs_to_playlist(playlist_id, song_ids)

Deprecated: prefer Mobileclient.add_songs_to_playlist().

Appends songs to a playlist. Returns a list of (song id, playlistEntryId) tuples that were added.

  • playlist_id – id of the playlist to add to.
  • song_ids – a list of song ids, or a single song id.

Playlists have a maximum size of 1000 songs.

Webclient.remove_songs_from_playlist(playlist_id, sids_to_match)

Deprecated: prefer Mobileclient.remove_entries_from_playlist().

Removes all copies of the given song ids from a playlist. Returns a list of removed (sid, eid) pairs.

  • playlist_id – id of the playlist to remove songs from.
  • sids_to_match – a list of song ids to match, or a single song id.

This does not always the inverse of a call to add_songs_to_playlist(), since multiple copies of the same song are removed.


Returns a dictionary with four keys: author, description, num_tracks, and title.


from playlist['shareToken'], or a playlist share url (https://play.google.com/music/playlist/<token>).

Note that tokens from urls will need to be url-decoded, eg AM...%3D%3D becomes AM...==.



Returns a list of dictionaries representing devices associated with the account.

Performing the Musicmanager OAuth flow will register a device of type 1.

Installing the Google Music app on an android or ios device and logging into it will register a device of type 2 or 3, which is used for streaming with the Mobileclient.

Here is an example response:

    u'deviceType': 1,  # laptop/desktop
    u'id': u'00:11:22:33:AA:BB',
    u'lastAccessedFormatted': u'May 24, 2015',
    u'lastAccessedTimeMillis': 1432468588200,  # utc-millisecond
    u'lastEventTimeMillis': 1434211605335,
    u'name': u'my computer'},
    u'deviceType': 2,  # android device
    u'carrier': u'Google',
    u'id': u'0x00112233aabbccdd',  # remove 0x when streaming
    u'lastAccessedFormatted': u'September 19, 2015',
    u'lastAccessedTimeMillis': 1442706069906,
    u'lastEventTimeMillis': 1435271137193,
    u'manufacturer': u'Asus',
    u'model': u'Nexus 7',
    u'name': u'my nexus 7'
    u'deviceType': 3,  # ios device
    u'id': u'ios:01234567-0123-0123-0123-0123456789AB',
    u'lastAccessedFormatted': u'June 25, 2015',
    u'lastAccessedTimeMillis': 1435271588780,
    u'lastEventTimeMillis': 1435271442417,
    u'name': u'my iphone'