Skip to content

Python API

Use the root exports for clients and utilities, and spotapi.models for results. The reference below is generated from the implementation's signatures and docstrings during the documentation build. Examples use Python 3.11+.

Reading this file on GitHub? Open the rendered API reference to see the generated signatures, types and docstrings below.

One-shot public reads

Public

Read public Spotify data without an API key or an explicit client.

Await single-result methods directly. Iterate page methods with async for; their limit controls page size, not the total result count. Each call owns an anonymous catalogue and closes it before returning or when its stream finishes. Use contextlib.aclosing when stopping a stream early. Reuse :class:Catalogue for several related operations.

Example::

hits = await Public.search("Daft Punk", types="track", limit=5)
for track in hits.tracks:
    print(track.name, track.uri)

parse_url staticmethod

parse_url(value: str, /, *, kind: ResourceInputKind | None = None) -> SpotifyResource

Normalize a Spotify URL, URI, or typed ID.

get async staticmethod

get(value: str, /, *, kind: ResourceInputKind | None = None, language: str | None = None) -> SpotifyItem

Fetch a Spotify resource from its URL, URI, or typed ID.

get_resource async staticmethod

get_resource(uri: str, operation: Operations) -> ObjectDict
get_resource(uri: str, operation: Operations, typ: type[_ResultT]) -> _ResultT
get_resource(uri: str, operation: Operations, typ: type[_ResultT] | None = None) -> ObjectDict | _ResultT

Execute a specific resource operation.

search async staticmethod

search(query: str, /, *, types: SearchInputKind | Iterable[SearchInputKind] = DEFAULT_SEARCH_TYPES, options: SearchOptions | None = None, limit: int | None = None, language: str | None = None) -> SearchResults

Search public categories and close the session before returning.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
types SearchInputKind | Iterable[SearchInputKind]

Category or categories; defaults to tracks, artists, albums, playlists and podcasts. Singular and plural names are accepted.

DEFAULT_SEARCH_TYPES
options SearchOptions | None

Advanced Spotify inclusion options.

None
limit int | None

Maximum results per category, from 1 to 100. Overrides options.limit; defaults to 20 without options.

None
language str | None

Optional language or locale, such as fr-CA.

None

Returns:

Type Description
SearchResults

Typed hits grouped by category, with empty tuples for categories

SearchResults

that were not requested or returned no usable results.

Raises:

Type Description
ValueError

Search text, categories, limit or language are invalid.

SpotAPIError

Authentication, transport or response parsing fails.

search_typed async staticmethod

search_typed(typ: type[_ResultT], operation: Operations, query: str, /, *, options: SearchOptions | None = None) -> AsyncGenerator[Sequence[_ResultT], None]

Stream typed result pages for a single persisted search operation.

search_tracks async staticmethod

search_tracks(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Track], None]

Stream typed pages of matching tracks.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Track], None]

One page of available tracks in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_albums async staticmethod

search_albums(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Album], None]

Stream typed pages of matching albums.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Album], None]

One page of available albums in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_artists async staticmethod

search_artists(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Artist], None]

Stream typed pages of matching artists.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Artist], None]

One page of available artists in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_playlists async staticmethod

search_playlists(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Playlist], None]

Stream typed pages of matching playlists.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Playlist], None]

One page of available playlists in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_podcasts async staticmethod

search_podcasts(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Podcast], None]

Stream typed pages of matching podcasts.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Podcast], None]

One page of available podcasts in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_episodes async staticmethod

search_episodes(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Episode], None]

Stream typed pages of matching episodes.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Episode], None]

One page of available episodes in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_audiobooks async staticmethod

search_audiobooks(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Audiobook], None]

Stream typed pages of matching audiobooks.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Audiobook], None]

One page of available audiobooks in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_users async staticmethod

search_users(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[User], None]

Stream typed pages of matching users.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[User], None]

One page of available users in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_authors async staticmethod

search_authors(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Author], None]

Stream typed pages of matching authors.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Author], None]

One page of available authors in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_genres async staticmethod

search_genres(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Genre], None]

Stream typed pages of matching genres.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Genre], None]

One page of available genres in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

iter_tracks async staticmethod

iter_tracks(query: str) -> AsyncGenerator[Track, None]

Yield tracks individually, hiding search-page boundaries.

iter_albums async staticmethod

iter_albums(query: str) -> AsyncGenerator[Album, None]

Yield albums individually, hiding search-page boundaries.

iter_artists async staticmethod

iter_artists(query: str) -> AsyncGenerator[Artist, None]

Yield artists individually, hiding search-page boundaries.

iter_playlists async staticmethod

iter_playlists(query: str) -> AsyncGenerator[Playlist, None]

Yield playlists individually, hiding search-page boundaries.

iter_podcasts async staticmethod

iter_podcasts(query: str) -> AsyncGenerator[Podcast, None]

Yield podcast shows individually, hiding search-page boundaries.

get_playlist async staticmethod

get_playlist(uri: str, /, *, language: str | None = None) -> PlaylistDetails

Read public playlist metadata from a URL, URI, or ID.

get_playlist_items async staticmethod

get_playlist_items(uri: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[PlaylistEntry], None]

Page through tracks, episodes and unavailable occurrences in source order.

iter_playlist_items async staticmethod

iter_playlist_items(uri: str, /, *, limit: int = 100) -> AsyncGenerator[PlaylistEntry, None]

Yield playlist occurrences individually, preserving duplicate songs.

get_playlist_tracks async staticmethod

get_playlist_tracks(uri: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[PlaylistTrack], None]

Page through available music tracks, including optional BPM and musical keys.

get_album_tracks async staticmethod

get_album_tracks(uri: str, /, *, limit: int = 50) -> AsyncGenerator[Sequence[AlbumTrack], None]

Read every album track in disc/track order, including albums over one page.

get_related_artists(uri: str, /, *, language: str | None = None) -> tuple[ArtistRelatedArtist, ...]

Explore the related artists shown on a public artist profile.

get_artist_releases async staticmethod

get_artist_releases(uri: str, /, *, kind: Literal['all', 'albums', 'singles', 'compilations'] = 'all', limit: int = 50) -> AsyncGenerator[Sequence[ArtistRelease], None]

Page through an artist's releases, newest first, flattening release groups.

get_radio async staticmethod

get_radio(seed: str, *, language: str | None = None) -> SpotifyResource | None

Resolve track, artist or album radio using a self-cleaning anonymous session.

get_playlist_recommendations async staticmethod

get_playlist_recommendations(value: str, *, limit: int = 20, skip: Iterable[str] = ()) -> tuple[RecommendedTrack, ...]

Read suggested playlist tracks without login or library changes.

get_canvas async staticmethod

get_canvas(track: str) -> Canvas | None

Read one available Canvas record; return None when it is unavailable.

get_canvases async staticmethod

get_canvases(tracks: Sequence[str]) -> tuple[Canvas, ...]

Batch up to 50 Canvas lookups and close the owned session afterward.

get_track_credits async staticmethod

get_track_credits(uri: str, /, *, language: str | None = None) -> TrackCredits

Discover the performers, writers and producers credited on a song.

get_artist_top_tracks async staticmethod

get_artist_top_tracks(uri: str) -> tuple[ArtistTopTrack, ...]

Read Spotify's public top-track selection and play counts for an artist.

get_profile async staticmethod

get_profile(value: str, /, *, limit: int = 20, language: str | None = None) -> PublicProfile

Read a public user's profile and first public playlists; no login needed.

get_artist async staticmethod

get_artist(uri: str, /, *, language: str | None = None) -> ArtistDetails

Fetch an artist profile and overview by Spotify URL, URI, or ID.

get_album async staticmethod

get_album(uri: str, /, *, language: str | None = None) -> AlbumDetails

Fetch album metadata and track information.

get_track async staticmethod

get_track(uri: str, /, *, language: str | None = None) -> TrackDetails

Fetch track metadata by Spotify URL, URI, or ID.

get_tracks async staticmethod

get_tracks(tracks: Sequence[str], /, *, language: str | None = None) -> tuple[TrackDetails, ...]

Fetch several tracks in input order using one client.

get_albums async staticmethod

get_albums(albums: Sequence[str], /, *, language: str | None = None) -> tuple[AlbumDetails, ...]

Fetch several albums in input order using one client.

get_artists async staticmethod

get_artists(artists: Sequence[str], /, *, language: str | None = None) -> tuple[ArtistDetails, ...]

Fetch several artists in input order using one client.

get_podcast async staticmethod

get_podcast(uri: str, /, *, language: str | None = None) -> PodcastDetails

Read podcast metadata from a URL, URI, or bare show ID.

get_audiobook async staticmethod

get_audiobook(uri: str, /, *, language: str | None = None) -> Audiobook

Read audiobook metadata from its Spotify show link, URI or ID.

get_audiobook_chapters async staticmethod

get_audiobook_chapters(uri: str, /, *, limit: int = 50) -> AsyncGenerator[Sequence[AudiobookChapter], None]

Stream chapters from an audiobook available in the current market.

get_podcast_episode async staticmethod

get_podcast_episode(uri: str, /, *, language: str | None = None) -> PodcastEpisodeDetails

Fetch a podcast episode by Spotify URL, URI, or ID.

get_podcast_episodes async staticmethod

get_podcast_episodes(uri: str, /, *, limit: int = 50) -> AsyncGenerator[Sequence[PodcastEpisodeDetails], None]

Stream a show's episodes in pages.

iter_podcast_episodes async staticmethod

iter_podcast_episodes(uri: str, /, *, limit: int = 50) -> AsyncGenerator[PodcastEpisodeDetails, None]

Yield a show's episodes individually, hiding pagination details.

list_charts staticmethod

list_charts() -> tuple[Chart, ...]

List editorial playlist shortcuts without creating a client.

get_chart async staticmethod

get_chart(key: str, *, language: str | None = None) -> PlaylistDetails

Read an editorial playlist's metadata by its chart shortcut.

get_similar_albums async staticmethod

get_similar_albums(track: str, *, limit: int = 10, language: str | None = None) -> tuple[Album, ...]

Recommend albums from a track using one automatically closed scope.

get_artist_discovered_on async staticmethod

get_artist_discovered_on(artist: str, /, *, language: str | None = None) -> tuple[Playlist | None, ...]

Read discovery playlists, retaining unavailable slots as None.

get_artist_events async staticmethod

get_artist_events(artist: str, *, language: str | None = None) -> tuple[Concert, ...]

Read an artist's upcoming concerts in the current request region.

get_colors async staticmethod

get_colors(image: str, *, language: str | None = None) -> CoverColors

Extract a Spotify image palette using one automatically closed scope.

fetch_many async staticmethod

fetch_many(values: Sequence[str], *, concurrency: int = 8, kind: ResourceInputKind | None = None, language: str | None = None) -> tuple[BatchItem[SpotifyItem], ...]

Read mixed URLs/URIs, keeping per-input failures instead of aborting.

get_embed async staticmethod

get_embed(value: str, *, kind: ResourceInputKind | None = None, browser: bool = False) -> Embed

Read public embed metadata, optionally using the Playwright browser extra.

lookup async staticmethod

lookup(value: str, *, kind: ResourceInputKind | None = None, fallback: bool = True) -> SpotifyItem | Embed

Read rich catalogue details with an explicitly typed public embed fallback.

Reusable catalogue scope

Catalogue

Reuse one session for typed catalogue reads and lazy page streams.

Use async with Catalogue() as spotify for anonymous reads. Supply an authenticated client to include resources visible to that account. Creating the catalogue makes no requests; authentication is deferred until a read. A closed catalogue cannot be reopened.

Parameters:

Name Type Description Default
client AsyncClient | AuthSession | None

Authenticated client or session to borrow without closing it.

None
proxy str | None

Proxy URL for an owned anonymous session.

None
queries Queries | None

Lower-level query interface to borrow instead of a client.

None
language str | None

Language or locale for an owned session, such as en-US. Configure this on the supplied session when borrowing one.

None

Raises:

Type Description
ValueError

Client, query owner, proxy or language options conflict.

Example::

async with Catalogue() as spotify:
    hits = await spotify.search("Daft Punk", types="artist")
    for artist in hits.artists:
        print(artist.name, artist.uri)

queries property

queries: Queries

Return the active lower-level query interface; require an open catalogue scope.

__init__

__init__(client: AsyncClient | AuthSession | None = None, *, proxy: str | None = None, queries: Queries | None = None, language: str | None = None, cache: ResponseCache | None = None) -> None

Configure an owned anonymous catalogue or borrow a supplied client or query owner.

__aenter__ async

__aenter__() -> Self

Enter this resource's asynchronous ownership scope.

__aexit__ async

__aexit__(_typ: object, error: BaseException | None, _tb: object) -> None

Release resources owned by this asynchronous scope.

close async

close() -> None

Drain catalogue queries and release only the session this catalogue owns.

parse_url

parse_url(value: str, /, *, kind: ResourceInputKind | None = None) -> SpotifyResource

Normalize a Spotify URL, URI, or typed ID.

get async

get(value: str, /, *, kind: ResourceInputKind | None = None) -> SpotifyItem

Fetch a Spotify resource from its URL, URI, or typed ID.

get_resource async

get_resource(uri: str, operation: Operations) -> ObjectDict
get_resource(uri: str, operation: Operations, typ: type[_ResultT]) -> _ResultT
get_resource(uri: str, operation: Operations, typ: type[_ResultT] | None = None) -> ObjectDict | _ResultT

Execute a specific resource operation.

search async

search(query: str, /, *, types: SearchInputKind | Iterable[SearchInputKind] = DEFAULT_SEARCH_TYPES, options: SearchOptions | None = None, limit: int | None = None) -> SearchResults

Search selected categories in one request.

Parameters:

Name Type Description Default
query str

Nonempty search text; surrounding whitespace is stripped.

required
types SearchInputKind | Iterable[SearchInputKind]

One category or an iterable of categories. Defaults to tracks, artists, albums, playlists and podcasts. Singular, plural and documented aliases are accepted and deduplicated.

DEFAULT_SEARCH_TYPES
options SearchOptions | None

Advanced Spotify inclusion options.

None
limit int | None

Results per category, from 1 to 100. Overrides the limit in options; defaults to 20 when neither is supplied.

None

Returns:

Type Description
SearchResults

Hits grouped by category. Unrequested or unavailable categories

SearchResults

are empty tuples. Incomplete search previews may be skipped.

Raises:

Type Description
ValueError

Query, categories or limit are invalid.

RuntimeError

This catalogue is outside its open context.

BaseClientError

Spotify returns an invalid search envelope.

Example::

results = await self.search("Daft Punk", types=("track", "artist"))
print(results.tracks[0].name)

search_typed

search_typed(typ: type[_ResultT], operation: Operations, query: str, /, *, options: SearchOptions | None = None) -> AsyncGenerator[Sequence[_ResultT], None]

Stream typed result pages for a single persisted search operation.

search_tracks

search_tracks(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Track], None]

Stream typed pages of matching tracks.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Track], None]

One page of available tracks in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_albums

search_albums(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Album], None]

Stream typed pages of matching albums.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Album], None]

One page of available albums in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_artists

search_artists(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Artist], None]

Stream typed pages of matching artists.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Artist], None]

One page of available artists in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_playlists

search_playlists(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Playlist], None]

Stream typed pages of matching playlists.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Playlist], None]

One page of available playlists in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_podcasts

search_podcasts(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Podcast], None]

Stream typed pages of matching podcasts.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Podcast], None]

One page of available podcasts in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_episodes

search_episodes(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Episode], None]

Stream typed pages of matching episodes.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Episode], None]

One page of available episodes in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_audiobooks

search_audiobooks(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Audiobook], None]

Stream typed pages of matching audiobooks.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Audiobook], None]

One page of available audiobooks in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_users

search_users(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[User], None]

Stream typed pages of matching users.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[User], None]

One page of available users in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_authors

search_authors(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Author], None]

Stream typed pages of matching authors.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Author], None]

One page of available authors in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

search_genres

search_genres(query: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[Genre], None]

Stream typed pages of matching genres.

Parameters:

Name Type Description Default
query str

Nonempty search text.

required
limit int

Page size from 1 to 100; this does not cap the total results.

100

Yields:

Type Description
AsyncGenerator[Sequence[Genre], None]

One page of available genres in Spotify's result order.

Note

Use contextlib.aclosing if iteration may stop early. Argument or request errors can surface when iteration begins.

iter_tracks async

iter_tracks(query: str) -> AsyncGenerator[Track, None]

Yield tracks individually, hiding search-page boundaries.

iter_albums async

iter_albums(query: str) -> AsyncGenerator[Album, None]

Yield albums individually, hiding search-page boundaries.

iter_artists async

iter_artists(query: str) -> AsyncGenerator[Artist, None]

Yield artists individually, hiding search-page boundaries.

iter_playlists async

iter_playlists(query: str) -> AsyncGenerator[Playlist, None]

Yield playlists individually, hiding search-page boundaries.

iter_podcasts async

iter_podcasts(query: str) -> AsyncGenerator[Podcast, None]

Yield podcast shows individually, hiding search-page boundaries.

get_playlist async

get_playlist(uri: str) -> PlaylistDetails

Read public playlist metadata from a URL, URI, or ID.

get_playlist_items async

get_playlist_items(uri: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[PlaylistEntry], None]

Page through tracks, episodes and unavailable occurrences in source order.

iter_playlist_items async

iter_playlist_items(uri: str, /, *, limit: int = 100) -> AsyncGenerator[PlaylistEntry, None]

Yield playlist occurrences individually, preserving duplicate songs.

get_playlist_tracks async

get_playlist_tracks(uri: str, /, *, limit: int = 100) -> AsyncGenerator[Sequence[PlaylistTrack], None]

Page through available music tracks, including optional BPM and musical keys.

get_album_tracks async

get_album_tracks(uri: str, /, *, limit: int = 50) -> AsyncGenerator[Sequence[AlbumTrack], None]

Read every album track in disc/track order, including albums over one page.

get_related_artists(uri: str) -> tuple[ArtistRelatedArtist, ...]

Explore the related artists shown on a public artist profile.

get_artist_discovered_on async

get_artist_discovered_on(uri: str) -> tuple[Playlist | None, ...]

Read an artist's Discovered On playlist selection in server order.

Unavailable slots are None. This is Spotify's bounded discovery selection, not every playlist containing the artist or a placement history. Availability depends on Spotify's current catalogue.

get_artist_releases async

get_artist_releases(uri: str, /, *, kind: Literal['all', 'albums', 'singles', 'compilations'] = 'all', limit: int = 50) -> AsyncGenerator[Sequence[ArtistRelease], None]

Page through an artist's releases, newest first, flattening release groups.

get_radio async

get_radio(seed: str) -> SpotifyResource | None

Resolve a track, artist or album into its Spotify radio playlist.

get_playlist_recommendations async

get_playlist_recommendations(value: str, *, limit: int = 20, skip: Iterable[str] = ()) -> tuple[RecommendedTrack, ...]

Get suggested tracks without changing the playlist.

get_canvases async

get_canvases(tracks: Sequence[str]) -> tuple[Canvas, ...]

Fetch available Canvas metadata in one protobuf request; no media is downloaded.

get_canvas async

get_canvas(track: str) -> Canvas | None

Return an available Canvas record, or None when Spotify supplies none.

get_track_credits async

get_track_credits(uri: str) -> TrackCredits

Discover the performers, writers and producers credited on a song.

get_artist_top_tracks async

get_artist_top_tracks(uri: str) -> tuple[ArtistTopTrack, ...]

Read Spotify's public top-track selection and play counts for an artist.

get_profile async

get_profile(value: str, /, *, limit: int = 20) -> PublicProfile

Read a public user's profile and first public playlists; no login needed.

get_artist async

get_artist(uri: str) -> ArtistDetails

Fetch an artist profile and overview by Spotify URL, URI, or ID.

get_album async

get_album(uri: str) -> AlbumDetails

Fetch album metadata and track information.

get_track async

get_track(uri: str) -> TrackDetails

Fetch track metadata by Spotify URL, URI, or ID.

get_tracks async

get_tracks(tracks: Sequence[str]) -> tuple[TrackDetails, ...]

Fetch track details in input order with up to eight concurrent reads.

get_albums async

get_albums(albums: Sequence[str]) -> tuple[AlbumDetails, ...]

Fetch album details in input order with up to eight concurrent reads.

get_artists async

get_artists(artists: Sequence[str]) -> tuple[ArtistDetails, ...]

Fetch artist details in input order with up to eight concurrent reads.

get_podcast async

get_podcast(uri: str) -> PodcastDetails

Read podcast metadata from a URL, URI, or bare show ID.

get_audiobook async

get_audiobook(uri: str) -> Audiobook

Read audiobook metadata from its Spotify show link, URI or ID.

get_podcast_episode async

get_podcast_episode(uri: str) -> PodcastEpisodeDetails

Fetch a podcast episode by Spotify URL, URI, or ID.

get_podcast_episodes

get_podcast_episodes(uri: str, /, *, limit: int = 50) -> AsyncGenerator[Sequence[PodcastEpisodeDetails], None]

Stream a show's episodes in pages.

get_audiobook_chapters

get_audiobook_chapters(uri: str, /, *, limit: int = 50) -> AsyncGenerator[Sequence[AudiobookChapter], None]

Stream chapters in order, subject to Spotify's market availability.

iter_podcast_episodes async

iter_podcast_episodes(uri: str, /, *, limit: int = 50) -> AsyncGenerator[PodcastEpisodeDetails, None]

Yield a show's episodes individually, hiding pagination details.

list_charts staticmethod

list_charts() -> tuple[Chart, ...]

List editorial playlist shortcuts without making requests.

get_chart async

get_chart(key: str) -> PlaylistDetails

Read chart metadata; paginate its tracks using the returned playlist URI.

get_similar_albums async

get_similar_albums(track: str, *, limit: int = 10) -> tuple[Album, ...]

Read album recommendations seeded by a track ID, URI or URL.

limit is from 1 to 50. An empty list is valid; a missing collection is a contract error. Recommendations can vary by request region.

get_artist_events async

get_artist_events(artist: str) -> tuple[Concert, ...]

Read upcoming artist concerts; returned inventory depends on region.

get_colors async

get_colors(image: str) -> CoverColors

Extract a palette from a spotify:image URI or Spotify CDN image URL.

No image bytes are downloaded. Supply artwork identity rather than a track ID; existing cover-art models expose the corresponding image URLs.

get_transcript async

get_transcript(episode: str) -> Transcript

Read episode captions using the explicitly supplied authenticated client.

fetch_many async

fetch_many(values: Sequence[str], *, kind: ResourceInputKind | None = None, concurrency: int = 8) -> tuple[BatchItem[SpotifyItem], ...]

Read resources with individual failures preserved in input order.

kind allows bare IDs of one resource type. Omit it for mixed typed URLs/URIs. Unlike strict plural getters, one invalid input does not abort the batch. Cancellation propagates and worker count is bounded.

lookup async

lookup(value: str, *, kind: ResourceInputKind | None = None, fallback: bool = True) -> SpotifyItem | Embed

Read a rich resource, optionally falling back to an explicit embed model.

Fallback is anonymous-only and handles unavailable/changed catalogue contracts or transient HTTP failures. It never retries account failures or presents sparse embed metadata as a complete detail model. Check isinstance(result, Embed) when you need to distinguish the source.

Synchronous scripts

SyncCatalogue

Reuse SpotAPI's async implementation from a synchronous script.

Use with SyncCatalogue() as spotify. A single Runner owns all I/O and shutdown in the calling thread. Do not call this from an existing event loop; use Catalogue there. Optional cookie authentication is scoped to this client. Returned models behave exactly like async results, without I/O.

close

close() -> None

Close catalogue, authentication and the owned event loop exactly once.

list_charts staticmethod

list_charts() -> tuple[Chart, ...]

List editorial shortcuts without opening a client.

get

get(value: str, /, *, kind: ResourceInputKind | None = None) -> SpotifyItem

Fetch a Spotify resource from its URL, URI, or typed ID.

search

search(query: str, /, *, types: SearchInputKind | Iterable[SearchInputKind] = DEFAULT_SEARCH_TYPES, options: SearchOptions | None = None, limit: int | None = None) -> SearchResults

Search selected categories in one request.

Parameters:

Name Type Description Default
query str

Nonempty search text; surrounding whitespace is stripped.

required
types SearchInputKind | Iterable[SearchInputKind]

One category or an iterable of categories. Defaults to tracks, artists, albums, playlists and podcasts. Singular, plural and documented aliases are accepted and deduplicated.

DEFAULT_SEARCH_TYPES
options SearchOptions | None

Advanced Spotify inclusion options.

None
limit int | None

Results per category, from 1 to 100. Overrides the limit in options; defaults to 20 when neither is supplied.

None

Returns:

Type Description
SearchResults

Hits grouped by category. Unrequested or unavailable categories

SearchResults

are empty tuples. Incomplete search previews may be skipped.

Raises:

Type Description
ValueError

Query, categories or limit are invalid.

RuntimeError

This catalogue is outside its open context.

BaseClientError

Spotify returns an invalid search envelope.

Example::

results = self.search("Daft Punk", types=("track", "artist"))
print(results.tracks[0].name)

get_playlist

get_playlist(uri: str) -> PlaylistDetails

Read public playlist metadata from a URL, URI, or ID.

get_related_artists(uri: str) -> tuple[ArtistRelatedArtist, ...]

Explore the related artists shown on a public artist profile.

get_radio

get_radio(seed: str) -> SpotifyResource | None

Resolve a track, artist or album into its Spotify radio playlist.

get_playlist_recommendations

get_playlist_recommendations(value: str, *, limit: int = 20, skip: Iterable[str] = ()) -> tuple[RecommendedTrack, ...]

Get suggested tracks without changing the playlist.

get_canvases

get_canvases(tracks: Sequence[str]) -> tuple[Canvas, ...]

Fetch available Canvas metadata in one protobuf request; no media is downloaded.

get_canvas

get_canvas(track: str) -> Canvas | None

Return an available Canvas record, or None when Spotify supplies none.

get_track_credits

get_track_credits(uri: str) -> TrackCredits

Discover the performers, writers and producers credited on a song.

get_artist_top_tracks

get_artist_top_tracks(uri: str) -> tuple[ArtistTopTrack, ...]

Read Spotify's public top-track selection and play counts for an artist.

get_profile

get_profile(value: str, /, *, limit: int = 20) -> PublicProfile

Read a public user's profile and first public playlists; no login needed.

get_artist

get_artist(uri: str) -> ArtistDetails

Fetch an artist profile and overview by Spotify URL, URI, or ID.

get_album

get_album(uri: str) -> AlbumDetails

Fetch album metadata and track information.

get_track

get_track(uri: str) -> TrackDetails

Fetch track metadata by Spotify URL, URI, or ID.

get_tracks

get_tracks(tracks: Sequence[str]) -> tuple[TrackDetails, ...]

Fetch track details in input order with up to eight concurrent reads.

get_albums

get_albums(albums: Sequence[str]) -> tuple[AlbumDetails, ...]

Fetch album details in input order with up to eight concurrent reads.

get_artists

get_artists(artists: Sequence[str]) -> tuple[ArtistDetails, ...]

Fetch artist details in input order with up to eight concurrent reads.

get_podcast

get_podcast(uri: str) -> PodcastDetails

Read podcast metadata from a URL, URI, or bare show ID.

get_audiobook

get_audiobook(uri: str) -> Audiobook

Read audiobook metadata from its Spotify show link, URI or ID.

get_podcast_episode

get_podcast_episode(uri: str) -> PodcastEpisodeDetails

Fetch a podcast episode by Spotify URL, URI, or ID.

get_chart

get_chart(key: str) -> PlaylistDetails

Read chart metadata; paginate its tracks using the returned playlist URI.

get_similar_albums

get_similar_albums(track: str, *, limit: int = 10) -> tuple[Album, ...]

Read album recommendations seeded by a track ID, URI or URL.

limit is from 1 to 50. An empty list is valid; a missing collection is a contract error. Recommendations can vary by request region.

get_artist_events

get_artist_events(artist: str) -> tuple[Concert, ...]

Read upcoming artist concerts; returned inventory depends on region.

get_artist_discovered_on

get_artist_discovered_on(artist: str) -> tuple[Playlist | None, ...]

Read the bounded discovery selection; unavailable slots remain None.

get_colors

get_colors(image: str) -> CoverColors

Extract a palette from a Spotify image URI or CDN image URL.

No image bytes are downloaded. Supply artwork identity rather than a track ID; existing cover-art models expose the corresponding image URLs.

get_transcript

get_transcript(episode: str) -> Transcript

Read episode captions; supply cookies when constructing SyncCatalogue.

fetch_many

fetch_many(values: Sequence[str], *, kind: ResourceInputKind | None = None, concurrency: int = 8) -> tuple[BatchItem[SpotifyItem], ...]

Read resources with per-input errors; kind allows same-type bare IDs.

get_embed

get_embed(value: str, *, kind: ResourceInputKind | None = None, browser: bool = False) -> Embed

Read public embed metadata in the owned event loop.

lookup

lookup(value: str, *, kind: ResourceInputKind | None = None, fallback: bool = True) -> SpotifyItem | Embed

Read catalogue details with an explicitly typed anonymous fallback.

get_playlist_items

get_playlist_items(value: str, *, limit: int = 100) -> Generator[Sequence[PlaylistEntry], None, None]

Iterate occurrence pages within the open synchronous scope.

get_playlist_tracks

get_playlist_tracks(value: str, *, limit: int = 100) -> Generator[Sequence[PlaylistTrack], None, None]

Iterate available music-track pages without collecting the whole playlist.

get_album_tracks

get_album_tracks(value: str, *, limit: int = 50) -> Generator[Sequence[AlbumTrack], None, None]

Iterate all album-track pages in disc and track order.

get_artist_releases

get_artist_releases(value: str, *, kind: Literal['all', 'albums', 'singles', 'compilations'] = 'all', limit: int = 50) -> Generator[Sequence[ArtistRelease], None, None]

Iterate discography pages without materializing the full release history.

get_podcast_episodes

get_podcast_episodes(value: str, *, limit: int = 50) -> Generator[Sequence[PodcastEpisodeDetails], None, None]

Iterate episode pages within the open synchronous scope.

get_audiobook_chapters

get_audiobook_chapters(value: str, *, limit: int = 50) -> Generator[Sequence[AudiobookChapter], None, None]

Iterate chapter pages, subject to the request region and account entitlement.

Transport and authorization

AsyncClient

Manage reusable HTTP and WebSocket transports.

Use :meth:new or async with to open the client, and :meth:close to release its transports. HTTP request methods require an open client and validate responses unless a non-success status is explicitly expected.

transport property

transport: HTTPClient

The open HTTP transport, returning responses without status validation.

Use this for protocols that interpret non-success statuses themselves. Prefer :meth:request for ordinary validated HTTP requests.

Raises:

Type Description
RuntimeError

If the client is not open.

websocket property

websocket: WebSocketClient

The open WebSocket transport; call its connect() to attach a socket.

Raises:

Type Description
RuntimeError

If the client is not open.

session property writable

session: AuthSession

Return the managed authentication session; require authorization first.

__init__

__init__(*, proxy: str | None = None) -> None

Create an unopened client.

Parameters:

Name Type Description Default
proxy str | None

Optional proxy URL for the underlying HTTP transport.

None

new async classmethod

new(*, proxy: str | None = None, **kwargs: Unpack[_AsyncClientOptions]) -> Self

Create and open a client.

Parameters:

Name Type Description Default
proxy str | None

Optional proxy URL for the underlying HTTP transport.

None
**kwargs Unpack[_AsyncClientOptions]

Additional keyword arguments for HTTPClient.

{}

Returns:

Type Description
Self

An initialized instance of the calling class.

from_cookies async classmethod

from_cookies(cookies: str | list[Mapping[str, Any]], *, proxy: str | None = None, language: str = 'en', **kwargs: Unpack[_AsyncClientOptions]) -> Self

Open and authorize a client that owns token renewal and transports.

Parameters:

Name Type Description Default
cookies str | list[Mapping[str, Any]]

Cookie-header text or exported browser-cookie records.

required
proxy str | None

Optional transport proxy URL.

None
language str

Language tag used for Spotify requests.

'en'
**kwargs Unpack[_AsyncClientOptions]

HTTP transport configuration, including retry settings.

{}

Returns:

Type Description
Self

An open authenticated client. Close it with await client.close().

Initialization failure closes the client before propagating the error. Use it with account/player helpers without constructing another session.

__aenter__ async

__aenter__() -> Self

Open the transports and return this client.

__aexit__ async

__aexit__(exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> None

Close the transports without suppressing context exceptions.

close async

close() -> None

Close both transports; concurrent callers share the same shutdown.

request async

request(method: Methods, url: str, *, authorized: bool = False, expected_statuses: tuple[int, ...] = (), max_attempts: int | None = None, retry_safe: bool | None = None, **kwargs: Unpack[Request]) -> Response

Send a request with optional managed Spotify authorization.

Parameters:

Name Type Description Default
method Methods

HTTP method.

required
url str

Absolute request URL. Managed credentials require an HTTPS Spotify host without embedded user credentials.

required
authorized bool

Add the session's current headers and renew once after a 401 for a replay-safe request. Requires an attached session.

False
expected_statuses tuple[int, ...]

Additional statuses that the caller handles, such as 404 when removing an already absent device.

()
max_attempts int | None

Total transport attempts. Setting this to 1 also disables automatic credential-renewal replay.

None
retry_safe bool | None

Permit replay of a known read-only operation, including catalogue POSTs. Defaults to safe HTTP methods.

None
**kwargs Unpack[Request]

Native transport options. Managed requests disable redirects to prevent forwarding credentials. Header names are merged without case distinctions; managed credential headers cannot be replaced.

{}

Returns:

Type Description
Response

A successful response, or an explicitly expected status.

Raises:

Type Description
RuntimeError

The client is closed or authorization is unavailable.

ValueError

Credentials target an invalid host or are overridden.

HTTPError

The request fails or returns an invalid JSON object.

get async

get(url: str, *, authorized: bool = False, expected_statuses: tuple[int, ...] = (), max_attempts: int | None = None, retry_safe: bool | None = None, **kwargs: Unpack[Request]) -> Response

Send a GET request and validate the response.

Parameters:

Name Type Description Default
url str

Absolute request URL.

required
authorized bool

Attach managed Spotify credentials; redirects are disabled.

False
expected_statuses tuple[int, ...]

Additional statuses handled by the caller.

()
max_attempts int | None

Transport attempt limit; 1 also disables auth replay.

None
retry_safe bool | None

Override method-based replay safety for this operation.

None
**kwargs Unpack[Request]

Native request options, including query, headers and body.

{}

Returns:

Type Description
Response

The validated response, or an explicitly expected status.

See request() for authorization, replay rules and raised errors.

post async

post(url: str, *, authorized: bool = False, expected_statuses: tuple[int, ...] = (), max_attempts: int | None = None, retry_safe: bool | None = None, **kwargs: Unpack[Request]) -> Response

Send a POST request and validate the response.

Parameters:

Name Type Description Default
url str

Absolute request URL.

required
authorized bool

Attach managed Spotify credentials; redirects are disabled.

False
expected_statuses tuple[int, ...]

Additional statuses handled by the caller.

()
max_attempts int | None

Transport attempt limit; 1 also disables auth replay.

None
retry_safe bool | None

Override method-based replay safety for this operation.

None
**kwargs Unpack[Request]

Native request options, including query, headers and body.

{}

Returns:

Type Description
Response

The validated response, or an explicitly expected status.

See request() for authorization, replay rules and raised errors.

put async

put(url: str, *, authorized: bool = False, expected_statuses: tuple[int, ...] = (), max_attempts: int | None = None, retry_safe: bool | None = None, **kwargs: Unpack[Request]) -> Response

Send a PUT request and validate the response.

Parameters:

Name Type Description Default
url str

Absolute request URL.

required
authorized bool

Attach managed Spotify credentials; redirects are disabled.

False
expected_statuses tuple[int, ...]

Additional statuses handled by the caller.

()
max_attempts int | None

Transport attempt limit; 1 also disables auth replay.

None
retry_safe bool | None

Override method-based replay safety for this operation.

None
**kwargs Unpack[Request]

Native request options, including query, headers and body.

{}

Returns:

Type Description
Response

The validated response, or an explicitly expected status.

See request() for authorization, replay rules and raised errors.

delete async

delete(url: str, *, authorized: bool = False, expected_statuses: tuple[int, ...] = (), max_attempts: int | None = None, retry_safe: bool | None = None, **kwargs: Unpack[Request]) -> Response

Send a DELETE request and validate the response.

Parameters:

Name Type Description Default
url str

Absolute request URL.

required
authorized bool

Attach managed Spotify credentials; redirects are disabled.

False
expected_statuses tuple[int, ...]

Additional statuses handled by the caller.

()
max_attempts int | None

Transport attempt limit; 1 also disables auth replay.

None
retry_safe bool | None

Override method-based replay safety for this operation.

None
**kwargs Unpack[Request]

Native request options, including query, headers and body.

{}

Returns:

Type Description
Response

The validated response, or an explicitly expected status.

See request() for authorization, replay rules and raised errors.

head async

head(url: str, *, authorized: bool = False, expected_statuses: tuple[int, ...] = (), max_attempts: int | None = None, retry_safe: bool | None = None, **kwargs: Unpack[Request]) -> Response

Send a HEAD request and validate the response.

Parameters:

Name Type Description Default
url str

Absolute request URL.

required
authorized bool

Attach managed Spotify credentials; redirects are disabled.

False
expected_statuses tuple[int, ...]

Additional statuses handled by the caller.

()
max_attempts int | None

Transport attempt limit; 1 also disables auth replay.

None
retry_safe bool | None

Override method-based replay safety for this operation.

None
**kwargs Unpack[Request]

Native request options, including query, headers and body.

{}

Returns:

Type Description
Response

The validated response, or an explicitly expected status.

See request() for authorization, replay rules and raised errors.

patch async

patch(url: str, *, authorized: bool = False, expected_statuses: tuple[int, ...] = (), max_attempts: int | None = None, retry_safe: bool | None = None, **kwargs: Unpack[Request]) -> Response

Send a PATCH request and validate the response.

Parameters:

Name Type Description Default
url str

Absolute request URL.

required
authorized bool

Attach managed Spotify credentials; redirects are disabled.

False
expected_statuses tuple[int, ...]

Additional statuses handled by the caller.

()
max_attempts int | None

Transport attempt limit; 1 also disables auth replay.

None
retry_safe bool | None

Override method-based replay safety for this operation.

None
**kwargs Unpack[Request]

Native request options, including query, headers and body.

{}

Returns:

Type Description
Response

The validated response, or an explicitly expected status.

See request() for authorization, replay rules and raised errors.

AuthSession

Manage Spotify web-player credentials and automatic token renewal.

Parameters:

Name Type Description Default
client AsyncClient

HTTP client owned by the session and closed by close().

required
Note

Entering the async context does not call authorize(). Use from_cookies() or explicitly await authorize() first.

token property

token: AccessToken

Return the current token, or raise if not yet authorized.

Raises:

Type Description
RuntimeError

If authorize() has not completed successfully.

authorized_headers property

authorized_headers: dict[str, str]

Construct the headers required for authenticated requests.

Raises:

Type Description
RuntimeError

If the token, client token, or server configuration is unavailable.

language property writable

language: str

Read or replace the validated language used by authorized requests.

__init__

__init__(client: AsyncClient, *, language: str = 'en') -> None

Own the supplied client's lifetime and prepare authorization and token refresh.

__aenter__ async

__aenter__() -> Self

Enter this resource's asynchronous ownership scope.

__aexit__ async

__aexit__(*exc_info: object) -> None

Release resources owned by this asynchronous scope.

from_cookies async classmethod

from_cookies(cookies: list[Mapping[str, Any]] | str, proxy: str | None = None, *, client: AsyncClient | None = None, language: str = 'en') -> Self

Create and authorize a session from Spotify web cookies.

Parameters:

Name Type Description Default
cookies list[Mapping[str, Any]] | str

A Cookie header or client-compatible cookie mappings.

required
proxy str | None

Optional HTTP proxy URL passed to the client factory.

None

Returns:

Type Description
Self

An authorized session responsible for its HTTP client.

Raises:

Type Description
HTTPError

If token retrieval fails with an HTTP error.

ValueError

If a required token response is empty.

Note

The client is closed if authorization fails or is cancelled.

authorize async

authorize() -> AccessToken

Obtain credentials and start automatic renewal if needed.

Returns:

Type Description
AccessToken

The newly issued access token with its client token.

refresh async

refresh(*, previous_token: str | None = None) -> AccessToken

Renew once when concurrent callers reject the same credentials.

close async

close() -> None

Stop token renewal and close the underlying client.

stop_refresh async

stop_refresh() -> None

Stop token renewal without closing the client's transports.

Accounts

Private

Bases: Account

Use account operations inside a managed cookie-authenticated scope.

Enter Private.from_cookies(cookie) with async with. It authorizes the session and closes its transports and token refresh task on exit. Inherited account helpers all share that session.

from_cookies async classmethod

from_cookies(cookies: str, *, proxy: str | None = None, language: str = 'en') -> AsyncGenerator[Self]

Open an account with explicit connection options and close it on exit.

Account

Read account settings and compose authenticated music and social helpers.

Construction makes no requests. The supplied client or session stays owned by the caller; this object never closes it. Use :class:Private for a managed cookie sign-in scope. Changes are explicit method calls, and batches may partially apply before an error is reported.

Parameters:

Name Type Description Default
client AsyncClient | AuthSession

Authorized client or session shared by every helper.

required
locale str

Account-page locale, such as en_US.

'en_US'
solver CaptchaSolver | None

Optional asynchronous CAPTCHA solver for profile changes.

None

Attributes:

Name Type Description
profile AccountProfile | None

Most recently fetched account settings, or None.

plan AccountPlan | None

Most recently fetched subscription card, or None.

library

Saved resources and artist follows.

liked_tracks

Track saves and paginated liked songs.

stats

Spotify affinity rankings.

profiles

Public profiles and explicit user follows.

notifications

Notification reads and explicit acknowledgement.

blends

Blend invitations and explicit joins.

__init__

__init__(client: AsyncClient | AuthSession, *, locale: str = 'en_US', solver: CaptchaSolver | None = None) -> None

Borrow an authenticated client; configure locale and an optional CAPTCHA solver.

get_profile async

get_profile() -> AccountProfile

Fetch current account settings and refresh the cached profile.

get_plan async

get_plan() -> AccountPlan

Fetch the account overview subscription card and refresh its CSRF state.

verify_login async

verify_login() -> bool

Return false for an expired or refused session; propagate other failures.

validate_profile async

validate_profile(**fields: str | bool) -> tuple[ProfileValidationError, ...]

Validate only supplied fields without saving profile changes.

edit_profile async

edit_profile(*, email: str | None = None, gender: str | None = None, birthdate: date | None = None, country: str | None = None, third_party_email: bool | None = None, password: str | None = None, token: str | None = None) -> AccountProfile | AccountChallenge

Merge supplied changes into freshly fetched account settings.

Parameters:

Name Type Description Default
email str | None

New email address, if editable for this account.

None
gender str | None

Value from the profile's available_genders.

None
birthdate date | None

New calendar birthdate.

None
country str | None

Code from the profile's available_countries.

None
third_party_email bool | None

Value for Spotify's third-party-email preference.

None
password str | None

Current password when Spotify requires it for an email change.

None
token str | None

Fresh CAPTCHA response; an injected solver is used if omitted.

None

Returns:

Type Description
AccountProfile | AccountChallenge

Updated settings, or a browser challenge that the caller must complete.

AccountProfile | AccountChallenge

Returning a challenge does not mean the requested changes were saved.

Raises:

Type Description
ValueError

No changes were supplied, a field is not editable, an option is invalid, or a required password or CAPTCHA token is empty.

CaptchaRequired

No CAPTCHA token or solver was supplied.

BaseClientError

Spotify returned invalid account settings.

HTTPError

Spotify rejected the request.

Note

Omitted fields remain unchanged. The mutation is sent once; after an ambiguous failure, read the current profile before deciding to retry.

logout_everywhere async

logout_everywhere() -> None

Revoke Spotify sessions everywhere and stop this session's token refresh.

change_password async

change_password(current_password: str, new_password: str) -> None

Change the account password using its current password; send once.

set_password async

set_password(new_password: str) -> None

Set the first password for an account created through another provider.

Player scopes

PlayerStatus

Observe Spotify Connect state and dispatch asynchronous event callbacks.

Register listeners before entering async with status.connect(). start() instead supervises reconnection until close(). Each scope owns its socket, controller registration and callback tasks; the supplied authentication session remains the caller's responsibility.

Parameters:

Name Type Description Default
session AuthSession | AsyncClient

Authorized client or session to borrow.

required
name str

Nonempty name for the control-only registration.

'SpotAPI'

Attributes:

Name Type Description
state PlayerState | None

Latest player snapshot, or None before one arrives.

devices tuple[Device, ...]

Devices advertised by the latest cluster update.

playback PlaybackUpdate | None

Latest renderer state-machine update, when available.

Note

Callbacks run in independent tasks. They must not block the event loop; pending callback work is bounded and excess callbacks may be dropped.

is_ready property

is_ready: bool

Report whether the dealer handshake and initial snapshot completed.

is_closed property

is_closed: bool

Report whether the observer has finished shutting down.

__init__

__init__(session: AuthSession | AsyncClient, *, name: str = 'SpotAPI') -> None

Borrow a session and prepare a scoped, non-rendering Connect controller.

event

event(callback: Callable[P, Coroutine[Any, Any, R]]) -> Callable[P, Coroutine[Any, Any, R]]

Register an async on_event callback and return it unchanged.

listen

listen(name: str | None = None) -> Callable[[Callable[P, Coroutine[Any, Any, R]]], Callable[P, Coroutine[Any, Any, R]]]

Create a decorator for an event name or an on_event callback name.

add_listener

add_listener(callback: Callable[..., Coroutine[Any, Any, object]], name: str | None = None) -> None

Register an additional async listener for a named dealer event.

remove_listener

remove_listener(callback: Callable[..., Coroutine[Any, Any, object]], name: str | None = None) -> None

Remove a specific async listener without removing other subscribers.

wait_for async

wait_for(event: Literal['pause', 'resume', 'queue_change', 'options_change'], *, check: Callable[[PlayerState], bool] | None = None, timeout: float | None = None) -> PlayerState
wait_for(event: str, *, check: Callable[..., bool] | None = None, timeout: float | None = None) -> Any
wait_for(event: str, *, check: Callable[..., bool] | None = None, timeout: float | None = None) -> Any

Wait for the next matching event; multiple arguments return a tuple.

wait_until_disconnected async

wait_until_disconnected() -> None

Wait until the current dealer connection ends.

wait_for_ack async

wait_for_ack(ack_id: str, *, timeout: float = 10) -> None

Wait for a target device's dealer acknowledgement, including an early reply.

wait_until_ready async

wait_until_ready() -> None

Wait for readiness, including across managed reconnection attempts.

This wait has no timeout and does not observe the task running start(). Bound it with asyncio.timeout or race that task when startup failure must interrupt the wait.

close async

close() -> None

Stop a managed listener or close the current connection scope.

start async

start(*, reconnect: bool = True) -> None

Listen until close(), reconnecting with bounded backoff on transient failures.

connect async

connect(*, timeout: float = 15) -> AsyncGenerator[Self, None]

Open one dealer connection and wait for its initial playback snapshot.

Parameters:

Name Type Description Default
timeout float

Positive, finite wait in seconds for each handshake and initial-snapshot phase. HTTP calls retain their own timeouts.

15

Yields:

Type Description
AsyncGenerator[Self, None]

This observer after readiness. Register event listeners before entry.

Raises:

Type Description
RuntimeError

A connection scope or startup attempt is already active.

ValueError

The timeout is not positive and finite.

TimeoutError

A handshake or snapshot does not arrive in time.

Note

Exit closes the socket and owned registrations, callbacks and timers. The supplied authentication session remains borrowed. For automatic reconnection, use start() instead of reopening this scope manually.

refresh async

refresh() -> PlayerState | None

Request a full snapshot; ordinary property reads never make requests.

process_message

process_message(packet: Mapping[str, Any]) -> None

Apply a decoded dealer envelope, including replayed captures.

Player

Bases: PlayerStatus

Observe and control an existing Spotify device using a borrowed session.

Enter player.connect() before sending commands, or run start() for managed reconnection. Property reads use local snapshots. Commands are sent once; an ambiguous failure requires checking fresh state before retrying. This client controls playback and does not decode or render audio.

Parameters:

Name Type Description Default
session AuthSession | AsyncClient

Authorized client or session; its lifetime stays with the caller.

required
device str | Device | None

Target playback device or full device ID. Defaults to the active device in the current snapshot.

None
source str | None

Optional source device ID for Connect routing.

None
name str

Name advertised by this instance's control-only registration.

'SpotAPI'

sleep_timer_remaining property

sleep_timer_remaining: float | None

Return seconds until the owned pause timer expires, or None.

__init__

__init__(session: AuthSession | AsyncClient, *, device: str | Device | None = None, source: str | None = None, name: str = 'SpotAPI') -> None

Borrow a session and optionally select existing source and target devices.

select

select(device: str | Device) -> None

Select a target device locally; transfer playback explicitly when needed.

command async

command(endpoint: str, *, wait: bool = True, timeout: float = 10, **arguments: Any) -> None

Send one native Connect command to the selected device.

Parameters:

Name Type Description Default
endpoint str

Native command name, such as pause or seek_to.

required
wait bool

Wait for a matching dealer ACK or a fresh snapshot proving a supported command's result. False returns after HTTP acceptance.

True
timeout float

Positive, finite acknowledgement wait in seconds. This does not include the HTTP request's own timeout.

10
**arguments Any

Native command fields; ordinary callers should prefer typed methods such as seek and set_queue.

{}

Raises:

Type Description
RuntimeError

This player is not connected and ready.

ValueError

The command, timeout or target device is invalid.

TypeError

wait is not a boolean.

TimeoutError

Neither acknowledgement nor state proof arrives in time.

Note

Commands are never replayed automatically. An ACK can precede media loading; observe playback events before depending on a loaded track.

pause async

pause() -> None

Pause the selected player, avoiding an already-paused request.

resume async

resume() -> None

Resume the selected player, avoiding an already-playing request.

next async

next() -> None

Skip to the next item on the selected Spotify player.

previous async

previous() -> None

Skip to the previous item on the selected Spotify player.

send_signal async

send_signal(signal_id: str) -> None

Send a signal advertised by the selected player's current state.

switch_to_video async

switch_to_video() -> None

Send switch-to-video only when advertised by the active player.

switch_to_audio async

switch_to_audio() -> None

Send switch-to-audio only when advertised by the active player.

seek async

seek(position_ms: int) -> None

Seek to a nonnegative millisecond position in the current track.

shuffle async

shuffle(enabled: bool) -> None

Set context shuffle explicitly; avoid sending unchanged options.

repeat async

repeat(mode: Literal['off', 'context', 'track']) -> None

Set repeat to off, context or track; avoid unchanged options.

volume async

volume(percent: int) -> None

Set the selected device's volume from zero to 100 percent.

transfer async

transfer(device: str | Device, *, play: bool | None = None) -> None

Transfer to an existing device, preserving paused state unless play is supplied.

play async

play(value: str, *, position_ms: int = 0, offset: int | None = None, track: str | None = None) -> None

Play a track, episode, album, playlist or artist from a Spotify link or URI.

add_to_queue async

add_to_queue(value: str) -> None

Queue a track or episode from its ID, URL or URI.

set_queue async

set_queue(tracks: Sequence[str | PlaybackTrack], *, previous: Sequence[PlaybackTrack] | None = None) -> None

Replace upcoming tracks, preserving history unless explicitly supplied.

clear_queue async

clear_queue() -> None

Remove manually queued items while keeping the context and history.

remove_from_queue async

remove_from_queue(value: str | PlaybackTrack) -> None

Remove one occurrence, using its UID when supplied.

restart async

restart() -> None

Seek the selected player to the beginning of its current item.

toggle async

toggle() -> None

Pause or resume according to the selected player's observed state.

is_liked async

is_liked(track: str | None = None) -> bool

Check whether a supplied or currently playing track is saved.

like async

like(track: str | None = None) -> None

Save a supplied or currently playing music track.

unlike async

unlike(track: str | None = None) -> None

Unsave a supplied or currently playing music track.

recents async

recents(*, limit: int = 20, offset: int = 0) -> tuple[RecentItem, ...]

Read a bounded page of the account's recent activity.

sleep_timer async

sleep_timer(seconds: float | None) -> None

Pause after a delay; pass None to cancel. The client must stay connected.

register_device async

register_device(name: str, *, client_version: str, platform_identifier: str, capabilities: Mapping[str, Any]) -> str

Register a device backed by your own renderer; this library does not decode audio.

report_state async

report_state(device_id: str, *, state_ref: Mapping[str, Any] | None, sub_state: Mapping[str, Any], debug_source: str) -> None

Report your registered renderer's state, with monotonic sequence numbers.

deregister_device async

deregister_device(device_id: str, *, observer_id: str | None = None, seq_num: int | None = None) -> None

Remove explicit device IDs. A HOBS ID is never inferred from a full ID.

Captions, media and sessions

Transcripts

Read episode captions with a borrowed authenticated client.

The caller owns the client. Availability depends on the episode, account and Spotify region; unavailable transcripts raise the normal HTTPError. No audio is downloaded or sent to a transcription service.

get async

get(episode: str) -> Transcript

Read timed captions for an episode ID, URI or share URL.

Requires an authenticated session. Missing/malformed envelopes raise BaseClientError; authentication and availability errors remain HTTPError.

LyricsClient

Read entitled lyrics using a borrowed authenticated client.

The caller owns the client and its lifetime. Lyrics are fetched on demand; this helper neither observes playback nor starts background tasks.

__init__

__init__(session: AuthSession | AsyncClient) -> None

Borrow an authenticated client; resolve lyrics hosts lazily.

get async

get(track: str, *, image_url: str | None = None) -> Lyrics

Fetch the available lyrics for one track.

Parameters:

Name Type Description Default
track str

Spotify track ID, URI or share URL.

required
image_url str | None

Optional HTTPS cover URL used by Spotify's image-aware route.

None

Returns:

Type Description
Lyrics

Text, provider metadata and any available line or syllable timings.

Raises:

Type Description
ValueError

The resource or supplied image URL is invalid.

HTTPError

Spotify rejects the request, including unavailable entitlement.

BaseClientError

Spotify returns malformed or missing lyrics.

Spotify's Premium entitlement is required. Unavailable lyrics are not represented as an empty successful result.

Media

Download returned public assets using an isolated unauthenticated transport.

No bearer headers are sent and redirects are disabled. Each download is bounded by max_bytes, including responses with no Content-Length. Existing output files are never overwritten. This does not download full tracks.

download_cover async

download_cover(source: Embed, destination: str | Path) -> Path

Save the first available artwork source; destination is an explicit file path.

download_preview async

download_preview(source: Embed, destination: str | Path, *, embed_cover: bool = False) -> Path

Save a published preview, optionally tagging it with cover art and title.

Cover embedding requires spotapi[media]. A tagging failure raises and leaves the downloaded preview available; existing files are never replaced. Only the published preview URL is used, never full audio.

download_canvas async

download_canvas(source: Canvas, destination: str | Path) -> Path

Save the Canvas asset returned by an entitled lookup.

SavedSession

Persist an sp_dc cookie in the operating system's credential store.

Requires spotapi[keyring] and a supported backend. No plaintext-file fallback is used. This object never includes the cookie in repr or info(). Saving does not validate the session; open() authorizes it with Spotify.

save

save(cookie: str) -> None

Store the raw sp_dc value; backend failures propagate without a file fallback.

info

info() -> SessionInfo

Check presence without returning credentials or claiming validity.

clear

clear() -> None

Remove this named credential if present.

open async

open(**options: Any) -> AsyncClient

Authorize a new managed client from the saved cookie, without a browser.

browser_login async

browser_login(*, saved: SavedSession | None = None, timeout: float = 180) -> AsyncClient

Open Spotify's login in a browser and return an authorized managed client.

Requires spotapi[browser] and a Playwright Chromium installation. The user completes login; SpotAPI does not request or store a password. Only the captured Spotify sp_dc cookie is retained, and only when saved is explicitly supplied. Reuse a valid saved session before opening a browser. Close the returned client after use. Closing the browser or timeout aborts.

Batches, caching and export

fetch_many async

fetch_many(values: Sequence[str], fetch: Callable[[str], Awaitable[T]], *, concurrency: int = 8) -> tuple[BatchItem[T], ...]

Read inputs with a bounded worker pool and return input-aligned outcomes.

Ordinary per-input failures are captured; cancellation and other BaseExceptions escape. Only concurrency worker tasks are created, rather than scheduling a task for every item. The caller owns fetch's connection scope. This helper is for independent reads, never mutations.

BatchItem dataclass

Bases: Generic[T]

One input's value or exception; cancellation always propagates.

index preserves duplicate inputs and original order. Check ok or use unwrap() to return the value or raise its original exception.

ok property

ok: bool

Whether the read completed, including a legitimate None result.

unwrap

unwrap() -> T

Return the successful value, otherwise raise the captured exception.

ResponseCache

Bound public metadata in memory, optionally persisting it to a directory.

Parameters:

Name Type Description Default
directory str | Path | None

Optional on-disk store. No embed HTML, cookies or headers are cached. Catalogue rejects this cache for authenticated scopes.

None
ttl float

Lifetime in seconds, default one day. Cached data can be stale.

86400
max_entries int

Maximum retained memory entries.

128
max_bytes int

Maximum JSON size of an individual response.

1024 * 1024

Cache corruption and I/O errors are misses, never successful empty results. Disk storage is explicitly caller-managed; clear its directory when no longer needed. Memory LRU eviction does not delete shared disk entries.

to_dict

to_dict(value: object) -> Any

Recursively export dataclasses, dates, enums and JSON-shaped containers.

Python field names are preserved. Dates use ISO format, tuples become lists, and unsupported objects/non-finite numbers raise TypeError rather than being converted to invented strings. The caller chooses what to export; personal account-model fields are included when explicitly passed. Exceptions export only their type and HTTP status, never message text.

from_dict

from_dict(cls: type[T], data: object) -> T

Deserialize a mapping into a typed dataclass.

Keys may use Python snake_case or Spotify camelCase. Unknown keys are ignored, and optional/default fields may be absent. Present values are validated recursively rather than silently replaced with None.

Parameters:

Name Type Description Default
cls type[T]

Target dataclass type.

required
data object

Spotify response object.

required

Returns:

Type Description
T

The recursively populated dataclass.

Raises:

Type Description
TypeError

A supplied value has the wrong type.

ValueError

A required field is missing.

Public fallback models

Embed dataclass

A public embed snapshot with optional preview and artwork URLs.

This deliberately differs from a rich catalogue detail model: absent play counts, availability and other Pathfinder-only fields are not fabricated. Only the entity is retained; embed-page tokens are discarded.

from_html classmethod

from_html(source: str, resource: SpotifyResource) -> Embed

Extract the entity from an embed page and verify its requested identity.

get_embed async

get_embed(value: str, *, kind: str | None = None, browser: bool = False, proxy: str | None = None) -> Embed

Read a public Spotify URL/URI through its embed page, without login.

This explicit alternative remains usable when persisted queries change. Bare IDs require a kind. It does not silently downgrade rich detail results.

Transcript dataclass

An episode's read-along captions, not a downloaded audio transcription.

Metadata may be absent. Speaker headings are omitted from timed lines; music/fallback captions are preserved when Spotify supplies their text.

from_dict classmethod

from_dict(body: Mapping[str, Any]) -> Transcript

Decode the read-along section envelope, rejecting malformed spoken cues.

TranscriptLine dataclass

One caption with its episode-relative start offset in milliseconds.

Concert dataclass

An upcoming event; date is Spotify's unmodified ISO string.

Listings can vary by region. A missing city/date is not inferred from the caller's location. This is metadata, not a ticket reservation.

from_dict classmethod

from_dict(value: Mapping[str, Any]) -> Concert

Decode a concert record and validate its identity and display title.

CoverColors dataclass

Spotify's raw, dark and light artwork colors as CSS hex strings.

from_dict classmethod

from_dict(body: Mapping[str, Any]) -> CoverColors

Decode the first requested image's extracted palette.

Chart dataclass

An editorial playlist shortcut, not a separate chart-data API.

uri property

uri: str

The backing playlist URI, usable with ordinary playlist pagination.