Skip to content

Models

Every entity is a frozen, slotted dataclass. Fields that only the tier-1 pathfinder payload can supply are typed | None, so a value of None means "not available from the source that answered", not "empty". Every model has a JSON-safe to_dict().

Some models need a cookie

Lyrics/LyricsLine and Transcript/TranscriptLine are populated by get_lyrics and get_transcript, which require a user sp_dc cookie — see the lyrics & cookies guide. Canvas, Credits, and UserProfile likewise come from cookie-authenticated calls (get_canvas / get_credits / get_user); Colors, Concert, and the discovery helpers are anonymous.

Track

spotify_scraper.models.Track dataclass

Track(
    id: str,
    uri: str,
    name: str,
    duration_ms: int,
    explicit: bool,
    playable: bool,
    preview_url: str | None,
    artists: tuple[ArtistRef, ...],
    images: tuple[Image, ...],
    release_date: datetime | None,
    album: AlbumRef | None = None,
    track_number: int | None = None,
    play_count: int | None = None,
    share_url: str | None = None,
)

Bases: ModelBase

A Spotify track.

Tier-1-only fields (album, track_number, play_count, share_url) stay None when built from embed data alone.

url property

url: str

Canonical open.spotify.com URL for this track.

Album

spotify_scraper.models.Album dataclass

Album(
    id: str,
    uri: str,
    name: str,
    album_type: str,
    images: tuple[Image, ...],
    release_date: datetime | None,
    artists: tuple[ArtistRef, ...],
    label: str | None = None,
    total_tracks: int | None = None,
    tracks: tuple[Track, ...] = (),
    copyrights: tuple[str, ...] = (),
    share_url: str | None = None,
)

Bases: ModelBase

A Spotify album.

album_type is the lowercased release kind ("album", "single", or "compilation"). Tier-1-only fields default to None or empty.

url property

url: str

Canonical open.spotify.com URL for this album.

Artist

spotify_scraper.models.Artist dataclass

Artist(
    id: str,
    uri: str,
    name: str,
    images: tuple[Image, ...],
    biography: str | None = None,
    followers: int | None = None,
    monthly_listeners: int | None = None,
    world_rank: int | None = None,
    top_tracks: tuple[Track, ...] = (),
    albums: tuple[AlbumRef, ...] = (),
    singles: tuple[AlbumRef, ...] = (),
    external_links: tuple[str, ...] = (),
    share_url: str | None = None,
)

Bases: ModelBase

A Spotify artist.

Tier-1-only fields (biography, followers, monthly_listeners, world_rank, share_url) default to None; discography collections default to empty tuples.

url property

url: str

Canonical open.spotify.com URL for this artist.

Playlist

spotify_scraper.models.Playlist dataclass

Playlist(
    id: str,
    uri: str,
    name: str,
    description: str = "",
    owner: UserRef | None = None,
    followers: int | None = None,
    images: tuple[Image, ...] = (),
    total_tracks: int | None = None,
    tracks: tuple[PlaylistTrack, ...] = (),
    share_url: str | None = None,
)

Bases: ModelBase

A Spotify playlist.

url property

url: str

Canonical open.spotify.com URL for this playlist.

PlaylistTrack

spotify_scraper.models.PlaylistTrack dataclass

PlaylistTrack(
    track: Track,
    added_at: datetime | None = None,
    added_by: UserRef | None = None,
)

Bases: ModelBase

A track entry in a playlist, with playlist-specific metadata.

Episode

spotify_scraper.models.Episode dataclass

Episode(
    id: str,
    uri: str,
    name: str,
    duration_ms: int,
    description: str = "",
    explicit: bool = False,
    playable: bool = True,
    release_date: datetime | None = None,
    images: tuple[Image, ...] = (),
    preview_url: str | None = None,
    show: ShowRef | None = None,
    share_url: str | None = None,
)

Bases: ModelBase

A podcast episode.

Tier-1-only fields (show, share_url) are None when the episode was built from an embed payload.

url property

url: str

Canonical open.spotify.com URL for this episode.

Show

spotify_scraper.models.Show dataclass

Show(
    id: str,
    uri: str,
    name: str,
    description: str = "",
    publisher: str | None = None,
    media_type: str | None = None,
    images: tuple[Image, ...] = (),
    total_episodes: int | None = None,
    episodes: tuple[Episode, ...] = (),
    topics: tuple[str, ...] = (),
    rating: float | None = None,
    share_url: str | None = None,
)

Bases: ModelBase

A podcast show.

Tier-1-only fields (publisher, media_type, total_episodes, rating, share_url) are None when the show was built from an embed payload.

url property

url: str

Canonical open.spotify.com URL for this show.

Image

spotify_scraper.models.Image dataclass

Image(
    url: str,
    width: int | None = None,
    height: int | None = None,
)

Bases: ModelBase

An image source with optional pixel dimensions.

ArtistRef

spotify_scraper.models.ArtistRef dataclass

ArtistRef(name: str, uri: str = '', id: str = '')

Bases: ModelBase

Lightweight reference to an artist.

Embed payloads provide name (and sometimes uri); pathfinder payloads provide all fields.

AlbumRef

spotify_scraper.models.AlbumRef dataclass

AlbumRef(
    id: str,
    uri: str,
    name: str,
    images: tuple[Image, ...] = (),
)

Bases: ModelBase

Lightweight reference to an album.

ShowRef

spotify_scraper.models.ShowRef dataclass

ShowRef(
    id: str,
    uri: str,
    name: str,
    publisher: str | None = None,
    images: tuple[Image, ...] = (),
)

Bases: ModelBase

Lightweight reference to a podcast show.

UserRef

spotify_scraper.models.UserRef dataclass

UserRef(name: str, uri: str = '')

Bases: ModelBase

Lightweight reference to a Spotify user.

SearchResults

spotify_scraper.models.SearchResults dataclass

SearchResults(
    query: str,
    tracks: tuple[Track, ...] = (),
    artists: tuple[Artist, ...] = (),
    albums: tuple[AlbumRef, ...] = (),
    playlists: tuple[Playlist, ...] = (),
    shows: tuple[ShowRef, ...] = (),
    episodes: tuple[Episode, ...] = (),
    total: int | None = None,
)

Bases: ModelBase

The results of an aggregate Spotify search.

Each tuple holds the hits for one entity type, reusing the existing entity and reference models. Search hits are sparse: tier-1-only fields absent from the search payload stay None/(). Albums and shows are returned as the lightweight :class:AlbumRef/:class:ShowRef (search returns no tracklist/discography for them).

total is the number of track matches Spotify reports for the query (the tracks section's totalCount); it is None when tracks were not among the requested types. The other sections do not surface a count.

Lyrics

spotify_scraper.models.Lyrics dataclass

Lyrics(
    lines: tuple[LyricsLine, ...],
    sync_type: str = "UNSYNCED",
    provider: str | None = None,
    language: str | None = None,
)

Bases: ModelBase

Lyrics for a track.

sync_type is "LINE_SYNCED" when start_ms offsets are meaningful, otherwise "UNSYNCED".

LyricsLine

spotify_scraper.models.LyricsLine dataclass

LyricsLine(start_ms: int, text: str)

Bases: ModelBase

A single lyrics line with its start offset.

Transcript

spotify_scraper.models.Transcript dataclass

Transcript(
    lines: tuple[TranscriptLine, ...],
    language: str | None = None,
    provider: str | None = None,
    is_auto_generated: bool | None = None,
)

Bases: ModelBase

A podcast episode's read-along transcript.

Episode-level language / provider / is_auto_generated are | None because their presence in the live envelope is unverified (see api/transcripts.py).

TranscriptLine

spotify_scraper.models.TranscriptLine dataclass

TranscriptLine(start_ms: int, text: str)

Bases: ModelBase

A single transcript line (cue) with its start offset.

Account

spotify_scraper.models.Account dataclass

Account(
    product: str | None = None,
    catalogue: str | None = None,
    country: str | None = None,
    on_demand: bool | None = None,
    preferred_locale: str | None = None,
    selected_language: str | None = None,
)

Bases: ModelBase

The logged-in account's product tier and locale, from product-state.

All fields are | None because the flat product-state body makes each key independently optional. is_premium is a derived @property rather than a stored field, so it is not part of dataclasses.fields() and is therefore absent from :meth:to_dict (and the from_dict round-trip).

is_premium property

is_premium: bool

Return True when the account's product tier is Premium.

This is derived from :attr:product (== "premium"); it is not a wire field and is intentionally absent from :meth:to_dict.

Colors

spotify_scraper.models.Colors dataclass

Colors(
    raw: str,
    dark: str,
    light: str,
    is_fallback: bool = False,
)

Bases: ModelBase

Dominant colors Spotify extracts from an image, for UI theming.

Each value is a #RRGGBB hex string. raw is the dominant color as extracted; dark and light are contrast-adjusted variants suitable as accents over dark and light backgrounds (Spotify uses them for the now-playing gradient). is_fallback is True when Spotify could not extract a color and returned its default instead.

Canvas

spotify_scraper.models.Canvas dataclass

Canvas(
    id: str,
    uri: str,
    url: str,
    canvas_type: str | None = None,
    file_id: str | None = None,
)

Bases: ModelBase

A track's Canvas: a short, silent, looping cover video.

url is a direct, non-DRM MP4 hosted on canvaz.scdn.co that you can download or embed. canvas_type is Spotify's loop style (e.g. "VIDEO_LOOPING" / "VIDEO_LOOPING_RANDOM"). id is the canvas id, derived from uri (spotify:canvas:<id>). Only some tracks have a Canvas; :meth:SpotifyClient.get_canvas returns None when one is absent.

UserProfile

spotify_scraper.models.UserProfile dataclass

UserProfile(
    id: str,
    uri: str,
    name: str,
    images: tuple[Image, ...] = (),
    followers_count: int | None = None,
    following_count: int | None = None,
    public_playlists: tuple[Playlist, ...] = (),
    public_playlists_total: int | None = None,
    recently_played_artists: tuple[ArtistRef, ...] = (),
    is_verified: bool | None = None,
)

Bases: ModelBase

A public Spotify user profile.

Returned by :meth:SpotifyClient.get_user (an authenticated feature). Every count and listing reflects only what the user has made public; recently_played_artists is populated for some accounts and empty for others (e.g. the official spotify account exposes none).

Credits

spotify_scraper.models.Credits dataclass

Credits(
    track_uri: str,
    track_title: str,
    roles: tuple[CreditRole, ...] = (),
    source_names: tuple[str, ...] = (),
)

Bases: ModelBase

A track's credits, grouped by role.

Returned by :meth:SpotifyClient.get_credits (an authenticated feature).

CreditRole

spotify_scraper.models.CreditRole dataclass

CreditRole(
    title: str, artists: tuple[CreditArtist, ...] = ()
)

Bases: ModelBase

A credit role (e.g. "Performers", "Writers", "Producers").

CreditArtist

spotify_scraper.models.CreditArtist dataclass

CreditArtist(
    name: str,
    uri: str = "",
    image_url: str | None = None,
    subroles: tuple[str, ...] = (),
)

Bases: ModelBase

A person credited on a track, with their sub-roles.

Concert

spotify_scraper.models.Concert dataclass

Concert(
    id: str,
    uri: str,
    title: str,
    start_date: str | None = None,
    city: str | None = None,
    artists: tuple[ArtistRef, ...] = (),
)

Bases: ModelBase

An upcoming live event for an artist.

Returned by :meth:SpotifyClient.get_artist_events. start_date is the raw ISO-8601 start time exactly as Spotify provides it (kept as a string for cross-version stability); artists are the acts on the bill.