> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sdk.anghami.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Content Model

> Typed IDs, the Content wrapper, and how music and video entities relate.

The SDK's content model has two design decisions worth understanding up front:

1. **Every ID is its own typed message** — `SongID`, `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`](https://github.com/anghami/sdk/blob/main/sdk/shared/v1/identifiers.proto):

```protobuf theme={null}
message SongID    { string value = 1; }
message AlbumID   { string value = 1; }
message ArtistID  { string value = 1; }
message PlaylistID{ string value = 1; }
message ShowID    { string value = 1; }
message SeasonID  { string value = 1; }
message EpisodeID { string value = 1; }
message MovieID   { string value = 1; }
```

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

```
Artist ──┐
         ├── owns ──> Album ── contains ──> Song
         └── tops ──> top tracks (Song)

Playlist ── contains ──> Song
```

* 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

```
Show ── has ──> Season ── has ──> Episode
Movie (standalone)
```

* 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

```protobuf theme={null}
message Content {
  oneof id {
    SongID song_id = 10;
    AlbumID album_id = 11;
    ArtistID artist_id = 12;
    PlaylistID playlist_id = 13;
    ShowID show_id = 14;
    SeasonID season_id = 15;
    EpisodeID episode_id = 16;
    MovieID movie_id = 17;
  }
  string title = 3;
  string subtitle = 4;
  Image artwork = 5;
}
```

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`](https://github.com/anghami/sdk/blob/main/sdk/shared/v1/content_type.proto) enum:

| Value                   | Meaning      |
| ----------------------- | ------------ |
| `CONTENT_TYPE_SONG`     | Song         |
| `CONTENT_TYPE_ALBUM`    | Album        |
| `CONTENT_TYPE_ARTIST`   | Artist       |
| `CONTENT_TYPE_PLAYLIST` | Playlist     |
| `CONTENT_TYPE_SHOW`     | Video series |
| `CONTENT_TYPE_SEASON`   | Season       |
| `CONTENT_TYPE_EPISODE`  | Episode      |
| `CONTENT_TYPE_MOVIE`    | Movie        |

## Media

Every entity carries an `Image` for artwork. See [`sdk/shared/v1/media.proto`](https://github.com/anghami/sdk/blob/main/sdk/shared/v1/media.proto) for image variants and sizing.
