Skip to main content
The SDK’s content model has two design decisions worth understanding up front:
  1. Every ID is its own typed messageSongID, AlbumID, EpisodeID, etc. There is no raw string or int64 ID anywhere in the public surface.
  2. A single Content wrapper unifies mixed lists — used in search results, library entries, and editorial sections where the items can be of different kinds.

Typed IDs

Defined in sdk/shared/v1/identifiers.proto:
Why messages instead of raw strings? Type safety propagates into every generated client — a Go function that accepts a SongID cannot be called with an AlbumID even though both wrap a string. This catches whole classes of bugs at compile time.

Music entity tree

  • An artist has a discography (GetArtistDiscography), top tracks (GetArtistTopTracks), and related artists (GetRelatedArtists).
  • An album has tracks (GetAlbumTracks).
  • A song has lyrics, when available (GetLyrics).

Video entity tree

  • A show response includes season summaries for navigation.
  • A season response includes its paginated episode list.
  • Movies are not nested in shows.

The Content wrapper

Used wherever a list can mix entity kinds:
  • Search results (any of song/album/artist/playlist/show/movie).
  • BrowseFeatured editorial sections.
  • LibraryService.GetHistory (mixed playback history).
  • BrowseGenres/GetGenreContent (genre-tagged content).
To act on a Content, branch on the oneof id arm and call the corresponding Get* RPC for full detail.

ContentType enum

When you only need to filter or tag (e.g. “give me liked items, songs only”), use the ContentType enum:

Media

Every entity carries an Image for artwork. See sdk/shared/v1/media.proto for image variants and sizing.