enum PlaylistDimension { MARKET } enum PlaylistStreamsOrderBy { ACTIVITY_DATE STREAMS } enum PlaylistListenersOrderBy { ACTIVITY_DATE LISTENERS } enum PlaylistStreamsAndListenersByDimensionOrderBy { ACTIVITY_DATE LISTENERS STREAMS STREAMS_PER_LISTENER } enum PlaylistStreamsByDimensionSummaryOrderBy { STREAMS_183_DAYS STREAMS_28_DAYS STREAMS_365_DAYS STREAMS_7_DAYS STREAMS_ALL_TIME } type PlaylistStreamsByDimensionSummary { dimension: String! streams183Days: Long streams28Days: Long streams365Days: Long streams7Days: Long streamsAllTime: Long } type PlaylistStreamsByDimension { """ Grand total streams across all dimension items for the given date range. Unlike timeseries (which is capped at 25 items), this sums every dimension item before the slice. Defaults match timeseries (ACTIVITY_DATE / ASC), so when orderBy/orderDir are the same between allStreamsTotal and timeseries, both fields share the same DataLoader cache entry. When startDate/endDate are omitted, the range falls back to the OWS service defaults. """ allStreamsTotal( startDate: Date endDate: Date countries: [String!] orderBy: PlaylistStreamsAndListenersByDimensionOrderBy! = ACTIVITY_DATE orderDir: OrderDir! = ASC ): Long summary( orderBy: PlaylistStreamsByDimensionSummaryOrderBy! = STREAMS_28_DAYS orderDir: OrderDir! = DESC ): [PlaylistStreamsByDimensionSummary!]! timeseries( startDate: Date endDate: Date countries: [String!] orderBy: PlaylistStreamsAndListenersByDimensionOrderBy! = ACTIVITY_DATE orderDir: OrderDir! = ASC ): [PlaylistStreamsAndListenersByDimensionTimeseries!]! } type PlaylistStreamsAndListenersByDimensionTimeseries { dimension: String! listeners: [PlaylistStreamsTimeSeries!]! listenersTotal: Long streams: [PlaylistStreamsTimeSeries!]! streamsTotal: Long } type PlaylistStreamsTimeSeries { date: Date! value: Long } type PlaylistFollowersTimeSeries { date: Date! value: Long } type PlaylistAnalytics { demographics: PlaylistDemographics! followersDailyChangeTimeseries( startDate: Date endDate: Date orderBy: PlaylistStreamsOrderBy! = ACTIVITY_DATE orderDir: OrderDir! = ASC ): [PlaylistFollowersTimeSeries!]! followersTimeseries( startDate: Date endDate: Date orderBy: PlaylistStreamsOrderBy! = ACTIVITY_DATE orderDir: OrderDir! = ASC ): [PlaylistFollowersTimeSeries!]! listeners(startDate: Date, endDate: Date, countries: [String!]): Long listenersTimeseries( startDate: Date endDate: Date countries: [String!] orderBy: PlaylistListenersOrderBy! = ACTIVITY_DATE orderDir: OrderDir! = ASC ): [PlaylistStreamsTimeSeries!]! """ Total listeners for the date range, ignoring any country filter. """ listenersTotal(startDate: Date, endDate: Date): Long playlist: Playlist! streams(startDate: Date, endDate: Date, countries: [String!]): Long streams183Days(streamCountries: [String!]): Long streams28Days(streamCountries: [String!]): Long streams365Days(streamCountries: [String!]): Long streams7Days(streamCountries: [String!]): Long streamsAllTime(streamCountries: [String!]): Long streamsByDimension( dimension: PlaylistDimension! ): PlaylistStreamsByDimension! streamsTimeseries( startDate: Date endDate: Date countries: [String!] orderBy: PlaylistStreamsOrderBy! = ACTIVITY_DATE orderDir: OrderDir! = ASC ): [PlaylistStreamsTimeSeries!]! """ Total streams for the date range, ignoring any country filter. """ streamsTotal(startDate: Date, endDate: Date): Long } type Playlist @key(fields: "playlistId source { storeId } storefront") { analytics: PlaylistAnalytics! countryCode: String followers: Int @deprecated(reason: "Use playlistFollowerCount") imageLocation: String @deprecated(reason: "Use playlistArtworkUrl") owner: String @shareable ownerCategory: OwnerCategory! @deprecated(reason: "Use playlistType") pastPlaylistTracklistDates(limit: Int, countries: [String!]): [Date!]! playlistArtworkUrl: String @shareable playlistCurator: PlaylistCurator! @shareable playlistFollowerCount: Float @shareable playlistGenres: [String!]! @shareable playlistId: ID! playlistName: String! @shareable playlistPlacements( """ Query placements for a specific historical date (format: YYYY-MM-DD). When provided, this returns the playlist's tracklist as it existed on that specific date, reconstructed from historical placement data. IMPORTANT: When using the date parameter, only `limit` and `offset` are supported. All other filter parameters (sortKey, sortDirection, distributors, etc.) will be rejected with a BAD_USER_INPUT error if provided alongside the date parameter. If date is not provided, returns current placements with full filtering support. """ date: Date limit: Int offset: Int sortKey: String sortDirection: String pastPlacementsOnly: Boolean minFollowers: Int playlistAppearances: String storefrontEnabled: Boolean streamCountries: [String!] playlistTypes: [PlaylistType!] curatorCountries: [String!] distributors: [Distributor!] ): TopPlaylistsPlacements! playlistTrackCount: Int @shareable playlistType: PlaylistType! @shareable playlistUri: String! @deprecated(reason: "Use playlistUrl") @shareable playlistUrl: String @shareable source: Store! storefront: String trackCount: Int @deprecated(reason: "Use playlistTrackCount") userDisplayName: String! @shareable } type PlaylistCurator { curatorCountry: String @shareable curatorId: String @shareable curatorName: String @shareable } """ Union type for playlist placements - returns either a placement with a real GlobalSoundRecording or a placeholder with Chartmetric metadata when the GSR has been removed from Neo4j. IN-16510: Prevents missing tracks from breaking playlist page display. """ union PlaylistPlacementResult = PlaylistPlacement | PlaylistPlacementPlaceholder type TopPlaylistsPlacements { """ Original placements field - does not include placeholder tracks. Use placementsV2 for complete tracklist including tracks removed from Neo4j. """ placements: [PlaylistPlacement!]! @deprecated( reason: "Use placementsV2 to get placeholder tracks for content removed from catalog" ) """ All placements in position order, including placeholders for tracks removed from Neo4j. Returns union type - use fragments to distinguish real vs placeholder tracks: ... on PlaylistPlacement { globalSoundRecording { id } } ... on PlaylistPlacementPlaceholder { trackName } """ placementsV2: [PlaylistPlacementResult!]! totalCount: Int! } """ Playlist placement for tracks that don't have GlobalSoundRecordings in Neo4j. Uses Chartmetric data as placeholder to prevent missing tracks from breaking playlist display. Frontend should render these WITHOUT links to Song pages (check __typename). IN-16510: Graceful degradation for content removed from catalog. """ type PlaylistPlacementPlaceholder { """ Artist name from Chartmetric data """ artistName: String """ List of storefront country codes where this placement appears (Apple Music only) """ availableStorefronts: [String!] @shareable """ Current position in the playlist """ currentPosition: Int @shareable """ Date the track was removed from the playlist """ dateRemoved: Date @shareable """ Number of days the track has been on the playlist """ daysOnPlaylist: Int @shareable """ Date the track was first added to the playlist """ firstAddedOnDate: Date @shareable """ Album artwork URL from Chartmetric """ imageUrl: String """ ISRC code identifying this track """ isrc: String! """ Date the track was last added to the playlist """ lastAddedOnDate: Date @shareable """ Highest position this track has reached """ peakPosition: Int @shareable """ The playlist containing this placement """ playlist: Playlist! """ Streaming metrics for this placement """ playlistPlacementStreams( streamCountries: [String!] ): PlaylistPlacementStreams! @shareable """ Change in position from previous snapshot """ positionChange: Int @shareable """ Previous position in the playlist """ previousPosition: Int @shareable """ Number of storefronts where this placement appears """ storefrontCount(playlistAppearances: String): Int @shareable streamsOnDate( date: Date! streamCountries: [String!] distributors: [Distributor!] ): Int @shareable """ Streams on the specific snapshot date being queried. Only populated for historical data queries (when date parameter is provided). """ streamsOnSnapshotDate: Int @shareable """ Track name from Chartmetric data """ trackName: String! } type PlaylistPlacementStreams { avgStreams7d: Int @shareable growthPeriods: [DeltaGrowth!]! @shareable topCountry: String @shareable } type DeltaGrowth { activeGrowthPercentage: Float @shareable activeValue: Float @shareable completionRate: Float @shareable growthPercentage: Float @shareable period: DeltaGrowthPeriod @shareable prevActiveValue: Float @shareable prevValue: Float @shareable value: Float @shareable } enum DeltaGrowthPeriod { _14_DAYS _180_DAYS _183_DAYS _1_DAY _1_TO_2_MONTHS _28_DAYS _2_TO_3_MONTHS _365_DAYS _3_TO_4_MONTHS _7_DAYS _90_DAYS _ALL_TIME } enum OwnerCategory { CURATED EDITORIAL USER_GENERATED } type PlaylistPlacement @key( fields: "playlist { playlistId source { storeId } storefront } globalSoundRecording { isrc }" ) { """ Completion rate metrics. Note: These fields return null for historical data queries (when date parameter is provided). """ added: Date @shareable @deprecated(reason: "Use lastAddedOnDate") """ List of storefront country codes where this placement appears (Apple Music only) """ availableStorefronts: [String!] @shareable """ Returns an aggregated list of CompanyBrands ordered by number of products under the brand. This field returns an empty array if the ISRC does not exist in the private catalog. """ brands: [CompanyBrand!]! completionRate183Days: Float @shareable completionRate1Day: Float @shareable completionRate28Days: Float @shareable completionRate365Days: Float @shareable completionRate7Days: Float @shareable completionRateAllTime: Float @shareable currentPosition: Int @shareable """ The date for which this placement data was queried. Only populated when querying historical data via the date parameter. """ date: Date @shareable dateRemoved: Date @shareable daysOnPlaylist: Int @shareable firstAddedOnDate: Date @shareable firstPlay: Date @shareable globalSoundRecording: GlobalSoundRecording! """ Indicates if this track appears on a "Now That's What I Call Music" compilation. true = track is on a compilation false = track is not on a compilation null = unable to determine (no release data available) Note: Only populated when insights_playlist_page_hide_compilation_art feature flag is enabled. """ inferredCompilation: Boolean @shareable isLatestEntry: Boolean! lastAddedOnDate: Date @shareable peakPosition: Int @shareable playlist: Playlist! playlistPlacementStreams( streamCountries: [String!] ): PlaylistPlacementStreams! @shareable position: Int @shareable positionChange: Int @shareable previousPosition: Int @shareable """ Storefront count metric. Note: This field returns null for historical data queries (when date parameter is provided). """ storefrontCount(playlistAppearances: String): Int @shareable streams: Int @shareable @deprecated(reason: "Use streams28Days") streams183Days: Int @shareable streams1Day: Int @shareable streams28Days: Int @shareable streams365Days: Int @shareable streams7Days: Int @shareable streamsAllTime: Int @shareable streamsOnDate( date: Date! streamCountries: [String!] distributors: [Distributor!] ): Int @shareable """ Streams on the specific snapshot date being queried. Only populated for historical data queries (when date parameter is provided). """ streamsOnSnapshotDate: Int @shareable } enum PlaylistType { ALGORITHMIC CHART CURATED EDITORIAL HOT_HITS NEW_MUSIC_FRIDAY PERSONALIZED RADIO STATION USER_GENERATED } type AnalyticsPlaylistId { storeId: Int! storePlaylistId: String! }