openapi: 3.0.1
info:
  description: The Delphi Products API for Consumer Analytics
  version: '2.0.40'
  title: Products API
servers:
  - description: API v2
    url: /v2
tags:
  - name: Amazon
    description: Amazon resource-related components
  - name: Auth
    description: Authentication and authorization-related components

paths:
  ############################################################################
  # Amazon Routes
  ############################################################################
  /amazon/tracks/streams:
    get:
      tags:
        - Amazon
      summary: Query for aggregate counts of Amazon Track Streams
#      operationId: delphi_api.v2.views.amazon_fake.AmazonMusicViewFake.get_tracks_streams
      operationId: delphi_api.v2.views.amazon.AmazonMusicView.get_tracks_streams
      description: |
        By passing in one or more `isrc` parameters, a `start_date`, `end_date`, and optional
        `country_code`, you can query aggregated data for track streams.
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/isrc_array'
        - $ref: '#/components/parameters/start_date'
        - $ref: '#/components/parameters/end_date'
        - $ref: '#/components/parameters/country_code'
        - $ref: '#/components/parameters/group_by'
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/offset'
      responses:
        200:
          description: search results matching criteria
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AmazonTrackStreamStatsResponse'

        400:
          $ref: '#/components/responses/InvalidInput'
        401:
          $ref: '#/components/responses/Unauthorized'
        500:
          $ref: '#/components/responses/InternalError'

  /amazon/playlist/tracks/streams:
    get:
      tags:
        - Amazon
      summary: Query for aggregate counts of Amazon Playlist Track Streams
#      operationId: delphi_api.v2.views.amazon_fake.AmazonMusicViewFake.get_playlist_tracks_streams
      operationId: delphi_api.v2.views.amazon.AmazonMusicView.get_playlist_tracks_streams
      description: |
        By passing in a `playlist_id`, one or more `isrc` parameters, a `start_date`, `end_date`,
        and optional `country_code`, you can query aggregated data for track streams in a playlist.
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/isrc_array'
        - $ref: '#/components/parameters/amazon_playlist_id'
        - $ref: '#/components/parameters/start_date'
        - $ref: '#/components/parameters/end_date'
        - $ref: '#/components/parameters/country_code'
        - $ref: '#/components/parameters/group_by'
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/offset'
      responses:
        200:
          description: search results matching criteria
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AmazonPlaylistTrackStreamStatsResponse'

        400:
          $ref: '#/components/responses/InvalidInput'
        401:
          $ref: '#/components/responses/Unauthorized'
        500:
          $ref: '#/components/responses/InternalError'

  /amazon/playlists/streams:
    get:
      tags:
        - Amazon
      summary: Query for aggregate counts of Amazon Playlist Track Streams
#      operationId: delphi_api.v2.views.amazon_fake.AmazonMusicViewFake.get_playlist_streams
      operationId: delphi_api.v2.views.amazon.AmazonMusicView.get_playlist_streams
      description: |
        By passing in one or more `playlist_id` parameters, a `start_date`, `end_date`, and optional
        `country_code`, you can query aggregated data for all track streams in a playlist.
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/amazon_playlist_id_array'
        - $ref: '#/components/parameters/start_date'
        - $ref: '#/components/parameters/end_date'
        - $ref: '#/components/parameters/country_code'
        - $ref: '#/components/parameters/group_by'
        - $ref: '#/components/parameters/limit'
        - $ref: '#/components/parameters/offset'
      responses:
        200:
          description: search results matching criteria
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AmazonPlaylistsStatsResponse'

        400:
          $ref: '#/components/responses/InvalidInput'
        401:
          $ref: '#/components/responses/Unauthorized'
        500:
          $ref: '#/components/responses/InternalError'


  ############################################################################
  # YouTube Routes
  ############################################################################

  ############################################################################
  # Spotify Routes – Redacted
  ############################################################################

  ############################################################################
  # Apple Routes – Redacted
  ############################################################################

  ############################################################################
  # Auth Routes
  ############################################################################
  /oauth/token:
    post:
      tags:
        - Auth
      summary: 'get an access token to make authenticated requests'
      operationId: delphi_api.v2.views.auth.OAuth2.post
      requestBody:
        description: 'access token request body'
        content:
          'application/json':
            schema:
              $ref: '#/components/schemas/authTokenRequestBody'
      responses:
        200:
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/authTokenResponseBody'

        400:
          $ref: '#/components/responses/InvalidInput'
        401:
          $ref: '#/components/responses/Unauthorized'
        500:
          $ref: '#/components/responses/InternalError'

components:
  securitySchemes:
    # Currently Swagger UI does not support the client_id and client_secret as POST body params to
    # the access token endpoint (only in the header). Since our implementation uses the body,
    # this section has been commented out.
    # This note is to save you the trouble of trying to make this work.
    #    oauth2Auth:
    #      type: oauth2
    #      flows:
    #        clientCredentials:
    #          tokenUrl: '/v2/oauth/token'
    #          scopes:
    #            read:files: 'Read data from the files resource'
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      x-bearerInfoFunc: delphi_api.auth.resource_protector.ProxyResourceProtector.decode_token

  parameters:
    amazon_playlist_id:
      name: playlist_id
      description: 'Amazon playlist ID'
      in: query
      required: true
      example: '00001f08-40d4-461a-a8dc-dd91da8b5cb6'
      schema:
        $ref: '#/components/schemas/amazon_playlist_id'
    amazon_playlist_id_array:
      name: playlist_id
      description: 'Amazon playlist ID (array)'
      in: query
      required: true
      schema:
        type: array
        items:
          $ref: '#/components/schemas/amazon_playlist_id'
      examples:
        B07YF2X2F3-B07Z5KBYXK:
          value: 'B07YF2X2F3-B07Z5KBYXK'
        B07YF2X2F4-B07Z5KBYXK:
          value: 'B07YF2X2F4-B07Z5KBYXK'
        B07YF2X2F5-B07Z5KBYXK:
          value: 'B07YF2X2F5-B07Z5KBYXK'
        'All Examples':
          value: ['B07YF2X2F3-B07Z5KBYXK', 'B07YF2X2F4-B07Z5KBYXK', 'B07YF2X2F5-B07Z5KBYXK']
    country_code:
      name: country_code
      description: 'Typically a lower-case two letter code for the country'
      in: query
      required: false
      example: 'us'
      schema:
        $ref: '#/components/schemas/country_code'
    end_date:
      name: end_date
      description: 'The latest date to consider in the query'
      in: query
      required: true
      example: '2019-09-01'
      schema:
        $ref: '#/components/schemas/iso_8601_date'
    group_by:
      name: group_by
      description: 'Specific term to group the data by. Currently only `date` (day) is supported.'
      in: query
      required: false
      example: 'date'
      schema:
        $ref: '#/components/schemas/group_by'
    isrc_array:
      name: isrc
      description: 'International Standard Recording Code (ISRC) number (array)'
      in: query
      required: true
      schema:
        type: array
        items:
          $ref: '#/components/schemas/isrc'
      examples:
        ESA011891255:
          value: 'ESA011891255'
        USSM11904174:
          value: 'USSM11904174'
        USSD11800343:
          value: 'USSD11800343'
        QMDA61852569:
          value: 'QMDA61852569'
        'All Example ISRCs':
          value: ['ESA011891255', 'USSM11904174', 'USSD11800343', 'QMDA61852569']
    limit:
      in: query
      name: limit
      description: |
        The maximum number of `items` to return in a single request. The default is **5000**.'
      example: 20
      schema:
        type: integer
        format: int32
        minimum: 0
        maximum: 5000
    start_date:
      name: start_date
      description: |
        The earliest date to consider in the query. The earliest date for Amazon is `2017-05-01`
      in: query
      required: true
      example: '2019-01-01'
      schema:
        $ref: '#/components/schemas/iso_8601_date'
    offset:
      in: query
      name: offset
      description: 'The number of `items` to offset for pagination.'
      example: 0
      schema:
        type: integer
        format: int32
        minimum: 0

  responses:
    ##########################################################################
    # Error Responses
    ##########################################################################
    InvalidInput:
      description: Invalid Input Response Body
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/invalidInputResponseBody'
    Unauthorized:
      description: Unauthorized (AuthError) Response Body
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/unauthorizedResponseBody'
    InternalError:
      description: Internal Error Response Body
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/internalErrorResponseBody'


  schemas:
    ##########################################################################
    # Request/Response Body Schemas
    ##########################################################################
    authTokenRequestBody:
      type: object
      properties:
        client_id:
          description: 'Required – `client_id` from identity provider credentials'
          type: string
          example: 'REPLACE_WITH_YOUR_CLIENT_ID'
        client_secret:
          description: 'Required – `client_secret` from identity provider credentials'
          type: string
          example: 'REPLACE_WITH_YOUR_CLIENT_SECRET'
        grant_type:
          description: '(optional) Defaults to `client_credentials` as the only currently supported method'
          type: string
          example: 'client_credentials'
    authTokenResponseBody:
      type: object
      properties:
        access_token:
          type: string
          example: 'EXAMPLE7J0JtkhGZzA6MscSiUH8qYwer...'
        scope:
          description: 'After authorizing, the available scopes are returned in a standard space deliminated format.'
          type: string
          example: 'read:files'
        expires_in:
          description: 'Length in seconds until token expiration.'
          type: number
          example: 86400
        expires_at:
          description: 'The timestamp of the token expiration in the (Unix) epoch format.'
          type: number
          format: int32
          example: 1569612083
        token_type:
          description: 'The token type, currently the only implementation is for `Bearer`.'
          type: string
          example: 'Bearer'
    invalidInputResponseBody:
      type: object
      description: InvalidInput Response Body
      properties:
        code:
          type: string
          example: invalid_input
        description:
          type: object
    unauthorizedResponseBody:
      type: object
      description: Unauthorized (AuthError) Response Body
      properties:
        code:
          type: string
          example: invalid_header
        description:
          type: string
          example: 'Unable to parse authentication token'
    internalErrorResponseBody:
      type: object
      description: Internal Error Response Body
      properties:
        code:
          type: string
          example: internal_error
        description:
          type: string
          example: 'The application encountered an internal error'
        details:
          type: string
          example: '(optional) more specific details)'

    ##########################################################################
    # Standardized Property Schemas
    ##########################################################################
    amazon_playlist_id:
      type: string
      format: uuid
      example: '00001f08-40d4-461a-a8dc-dd91da8b5cb6'
    count:
      type: integer
      description: 'The number of ``items`` returned in the response'
      format: int32
      example: 25
      default: 0
    country_code:
      type: string
      description: 'Typically a lower-case two letter code for the country'
      example: 'us'
    group_by:
      description: 'Currently only grouping by `date` (day) is supported'
      type: string
      enum:
        - date
    stream_count:
      type: integer
      description: 'Number of streams'
      example: 123456
      default: 0
    iso_8601_date:
      type: string
      description: 'ISO 8601 date in format `YYYY-MM-DD`'
      format: date
      pattern: '^\d{4}-\d{2}-\d{2}$'
      example: '2019-01-01'
    isrc:
      type: string
      description: 'The International Standard Recording Code (ISRC) for a song.'
      pattern: '^[A-Z]{2}-?\w{3}-?\d{2}-?\d{5}$'
      example: 'USSM11904174'
    report_date:
      type: string
      description: '(optional) If group_by provided, this will include the date'
      format: date
      pattern: '^\d{4}-\d{2}-\d{2}$'
      nullable: true

    ############################################################################
    # Amazon Objects
    ############################################################################
    AmazonDeviceType:
      type: object
      properties:
        desktop:
          $ref: '#/components/schemas/stream_count'
        cell_phone_app_mobile_web:
          $ref: '#/components/schemas/stream_count'
        tablet_app:
          $ref: '#/components/schemas/stream_count'
        in_dash_car_integration:
          $ref: '#/components/schemas/stream_count'
        mobile_to_car_tether:
          $ref: '#/components/schemas/stream_count'
        connected_home_tv:
          $ref: '#/components/schemas/stream_count'
        connected_home_audio_tether:
          $ref: '#/components/schemas/stream_count'
        gaming_system:
          $ref: '#/components/schemas/stream_count'
        voice_controlled_device:
          $ref: '#/components/schemas/stream_count'
        other:
          $ref: '#/components/schemas/stream_count'

    AmazonEngagement:
      type: object
      properties:
        lean_forward:
          $ref: '#/components/schemas/stream_count'
        lean_back:
          $ref: '#/components/schemas/stream_count'

    AmazonOperatingSystem:
      type: object
      properties:
        alexa:
          $ref: '#/components/schemas/stream_count'
        android:
          $ref: '#/components/schemas/stream_count'
        fire_os:
          $ref: '#/components/schemas/stream_count'
        ios:
          $ref: '#/components/schemas/stream_count'
        mac_osx:
          $ref: '#/components/schemas/stream_count'
        third_party_device_os:
          $ref: '#/components/schemas/stream_count'
        unknown:
          $ref: '#/components/schemas/stream_count'
        windows:
          $ref: '#/components/schemas/stream_count'

    AmazonReferralSourceType:
      type: object
      properties:
        websites_or_hyperlinks:
          $ref: '#/components/schemas/stream_count'
        search_result:
          $ref: '#/components/schemas/stream_count'
        sme_promotional_marketing_inventory:
          $ref: '#/components/schemas/stream_count'
        sme_paid_promotion:
          $ref: '#/components/schemas/stream_count'
        recommended_content_promotions:
          $ref: '#/components/schemas/stream_count'
        not_available:
          $ref: '#/components/schemas/stream_count'

    AmazonSelectionSourceType:
      type: object
      properties:
        album:
          $ref: '#/components/schemas/stream_count'
        artist:
          $ref: '#/components/schemas/stream_count'
        auto_playlist:
          $ref: '#/components/schemas/stream_count'
        prime_playlist:
          $ref: '#/components/schemas/stream_count'
        prime_station:
          $ref: '#/components/schemas/stream_count'
        songs:
          $ref: '#/components/schemas/stream_count'
        user_playlist:
          $ref: '#/components/schemas/stream_count'

    AmazonStreamSourceType:
      type: object
      properties:
        search_results_page:
          $ref: '#/components/schemas/stream_count'
        artist_profile_page:
          $ref: '#/components/schemas/stream_count'
        content_pages:
          $ref: '#/components/schemas/stream_count'
        user_created_playlists:
          $ref: '#/components/schemas/stream_count'
        followed_saved_third_party:
          $ref: '#/components/schemas/stream_count'
        promotional:
          $ref: '#/components/schemas/stream_count'
        recent_activity:
          $ref: '#/components/schemas/stream_count'
        api_partner:
          $ref: '#/components/schemas/stream_count'
        semi_interactive_radio_station:
          $ref: '#/components/schemas/stream_count'
        charts_and_algorithmic:
          $ref: '#/components/schemas/stream_count'
        all_other_areas:
          $ref: '#/components/schemas/stream_count'

    AmazonTrackStreamStats:
      type: object
      properties:
        isrc:
          $ref: '#/components/schemas/isrc'
        date:
          $ref: '#/components/schemas/report_date'
        country_code:
          type: string
          description: 'Country code'
          example: 'us'
        streams:
          type: integer
          example: 123456
          description: 'Grand total number of streams'
        device_type:
          $ref: '#/components/schemas/AmazonDeviceType'
        engagement:
          $ref: '#/components/schemas/AmazonEngagement'
        operating_system:
          $ref: '#/components/schemas/AmazonOperatingSystem'
        referral_source_type:
          $ref: '#/components/schemas/AmazonReferralSourceType'
        selection_source_type:
          $ref: '#/components/schemas/AmazonSelectionSourceType'
        stream_source_type:
          $ref: '#/components/schemas/AmazonStreamSourceType'
        device_type_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `device_type`'
        engagement_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `engagement`'
        operating_system_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `operating_system`'
        referral_source_type_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `referral_source_type`'
        selection_source_type_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `selection_source_type`'
        stream_source_type_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `stream_source_type`'
        royalty_bearing_play_yes:
          type: integer
          example: 123456
        royalty_bearing_play_no:
          type: integer
          example: 123456

    AmazonPlaylistTrackStreamStats:
      type: object
      properties:
        isrc:
          $ref: '#/components/schemas/isrc'
        date:
          $ref: '#/components/schemas/report_date'
        playlist_id:
          $ref: '#/components/schemas/amazon_playlist_id'
        country_code:
          type: string
          description: 'Country code'
          example: 'us'
        streams:
          type: integer
          example: 123456
          description: 'Grand total number of streams'
        device_type:
          $ref: '#/components/schemas/AmazonDeviceType'
        engagement:
          $ref: '#/components/schemas/AmazonEngagement'
        operating_system:
          $ref: '#/components/schemas/AmazonOperatingSystem'
        referral_source_type:
          $ref: '#/components/schemas/AmazonReferralSourceType'
        selection_source_type:
          $ref: '#/components/schemas/AmazonSelectionSourceType'
        stream_source_type:
          $ref: '#/components/schemas/AmazonStreamSourceType'
        device_type_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `device_type`'
        engagement_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `engagement`'
        operating_system_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `operating_system`'
        referral_source_type_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `referral_source_type`'
        selection_source_type_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `selection_source_type`'
        stream_source_type_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `stream_source_type`'
        royalty_bearing_play_yes:
          type: integer
          example: 123456
        royalty_bearing_play_no:
          type: integer
          example: 123456

    AmazonPlaylistStats:
      type: object
      properties:
        playlist_id:
          $ref: '#/components/schemas/amazon_playlist_id'
        date:
          $ref: '#/components/schemas/report_date'
        country_code:
          type: string
          description: 'Country code'
          example: 'us'
        streams:
          type: integer
          example: 123456
          description: 'Grand total number of streams'
        device_type:
          $ref: '#/components/schemas/AmazonDeviceType'
        engagement:
          $ref: '#/components/schemas/AmazonEngagement'
        operating_system:
          $ref: '#/components/schemas/AmazonOperatingSystem'
        referral_source_type:
          $ref: '#/components/schemas/AmazonReferralSourceType'
        selection_source_type:
          $ref: '#/components/schemas/AmazonSelectionSourceType'
        stream_source_type:
          $ref: '#/components/schemas/AmazonStreamSourceType'
        device_type_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `device_type`'
        engagement_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `engagement`'
        operating_system_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `operating_system`'
        referral_source_type_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `referral_source_type`'
        selection_source_type_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `selection_source_type`'
        stream_source_type_streams:
          type: integer
          example: 123456
          description: 'Total number of streams for `stream_source_type`'
        royalty_bearing_play_yes:
          type: integer
          example: 123456
        royalty_bearing_play_no:
          type: integer
          example: 123456

    AmazonTrackStreamStatsResponse:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/AmazonTrackStreamStats'
        count:
          $ref: '#/components/schemas/count'

    AmazonPlaylistTrackStreamStatsResponse:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/AmazonPlaylistTrackStreamStats'
        count:
          $ref: '#/components/schemas/count'

    AmazonPlaylistsStatsResponse:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/AmazonPlaylistStats'
        count:
          $ref: '#/components/schemas/count'
