swagger: "2.0"
schemes:
  - https
host: identity.api.npr.org
info:
  contact:
    email: NPROneEnterprise@npr.org
    name: NPR One Enterprise Team
    url: https://dev.npr.org
    x-twitter: NPR
  description: The entry point to user-specific information
  termsOfService: https://dev.npr.org/guide/prerequisites/terms-of-use
  title: NPR Identity Service
  version: "2"
  x-apisguru-categories:
    - entertainment
  x-logo:
    url: https://twitter.com/NPR/profile_image?size=original
  x-origin:
    - format: swagger
      url: https://identity.api.npr.org/v2/swagger.json
      version: "2.0"
  x-providerName: npr.org
  x-serviceName: identity
externalDocs:
  description: Learn more at the NPR One Developer Center
  url: https://dev.npr.org/guide/services/identity
consumes:
  - application/json
  - application/vnd.collection.doc+json
produces:
  - application/json
  - application/vnd.collection.doc+json
securityDefinitions:
  oauth2:
    authorizationUrl: https://authorization.api.npr.org/v2/authorize
    flow: accessCode
    scopes:
      identity.readonly: See your personal information, such as your first name, last name, and favorite station.
      identity.write: Update your personal information, such as your favorite station(s) or program(s) you follow, on your behalf.
      listening.readonly: See your NPR One listening history and get audio recommendations.
      listening.write: Record that you have heard, marked as interesting, and/or skipped NPR One stories in order to personalize future audio recommendations.
      localactivation: Connect you with your local NPR member station for communication purposes.
    tokenUrl: https://authorization.api.npr.org/v2/token
    type: oauth2
parameters:
  Authorization:
    description: Your access token from the Authorization Service. Should start with `Bearer`, followed by a space, followed by the token.
    in: header
    name: Authorization
    required: true
    type: string
  X-Advertising-ID:
    description: A device-specific advertising identifier, if possible. Apple's IDFA is an example.
    in: header
    name: X-Advertising-ID
    required: false
    type: string
responses:
  400WithDocument:
    description: A bad request; generally, one or more parameters passed in were incorrect or missing
    headers:
      X-RateLimit-Limit:
        description: The number of allowed requests in the current period
        type: integer
      X-RateLimit-Remaining:
        description: The number of remaining requests in the current period
        type: integer
      X-RateLimit-Reset:
        description: The number of seconds left in the current period
        type: integer
    schema:
      $ref: "#/definitions/ErrorDocument"
  401WithDocument:
    description: The client is not authorized to complete this request. Check to ensure a valid access token was passed in the headers.
    schema:
      $ref: "#/definitions/ErrorDocument"
  404WithDocument:
    description: The resource with the requested ID could not be found, and the server was unable to complete the request.
    headers:
      X-RateLimit-Limit:
        description: The number of allowed requests in the current period
        type: integer
      X-RateLimit-Remaining:
        description: The number of remaining requests in the current period
        type: integer
      X-RateLimit-Reset:
        description: The number of seconds left in the current period
        type: integer
    schema:
      $ref: "#/definitions/ErrorDocument"
  429WithDocument:
    description: The client has exceeded the number of daily calls as per their rate limit. For now, this only applies to prototype applications and untrusted clients. Trusted clients will never be rate-limited, nor will any production apps.
    headers:
      X-RateLimit-Limit:
        description: The number of allowed requests in the current period
        type: integer
      X-RateLimit-Remaining:
        description: The number of remaining requests in the current period
        type: integer
      X-RateLimit-Reset:
        description: The number of seconds left in the current period
        type: integer
    schema:
      $ref: "#/definitions/ErrorDocument"
  500WithDocument:
    description: A server error
    headers:
      X-RateLimit-Limit:
        description: The number of allowed requests in the current period
        type: integer
      X-RateLimit-Remaining:
        description: The number of remaining requests in the current period
        type: integer
      X-RateLimit-Reset:
        description: The number of seconds left in the current period
        type: integer
    schema:
      $ref: "#/definitions/ErrorDocument"
  503WithDocument:
    description: The system is undergoing maintenance and we are unable to fulfill this request. Look for a `Retry-After` header to see the predicted time the system will be back up.
    headers:
      Retry-After:
        description: The predicted time the system will be back up
        format: date-time
        type: string
    schema:
      $ref: "#/definitions/ErrorDocument"
  IdentitySuccess:
    description: The request was successful
    headers:
      X-RateLimit-Limit:
        description: The number of allowed requests in the current period
        type: integer
      X-RateLimit-Remaining:
        description: The number of remaining requests in the current period
        type: integer
      X-RateLimit-Reset:
        description: The number of seconds left in the current period
        type: integer
    schema:
      $ref: "#/definitions/UserDocument"
paths:
  /v2/following:
    post:
      consumes:
        - application/json
      description: After a successful call, this returns a User document with an updated list of affiliations.
      operationId: postFollowing
      parameters:
        - $ref: "#/parameters/Authorization"
        - description: A JSON-serialized object which contains data about a user affiliation such as the aggregation ID, affiliation rating, aggregation URL, days since last listen, and following status.
          in: body
          name: body
          required: true
          schema:
            $ref: "#/definitions/Affiliation"
      responses:
        "201":
          $ref: "#/responses/IdentitySuccess"
        "400":
          $ref: "#/responses/400WithDocument"
        "401":
          $ref: "#/responses/401WithDocument"
        "429":
          $ref: "#/responses/429WithDocument"
        "500":
          $ref: "#/responses/500WithDocument"
        "503":
          $ref: "#/responses/503WithDocument"
      security:
        - oauth2:
            - identity.write
      summary: Update the following status of the logged-in user for a particular aggregation
      tags:
        - identity
  /v2/stations:
    put:
      description: Right now, only the primary station can be changed. Previously selected stations will not be deleted, but the new station will be moved to first in the array.
      operationId: updateStations
      parameters:
        - $ref: "#/parameters/Authorization"
        - description: A JSON-serialized array of station IDs
          in: body
          name: body
          required: false
          schema:
            items:
              type: integer
            type: array
      responses:
        "201":
          $ref: "#/responses/IdentitySuccess"
        "400":
          $ref: "#/responses/400WithDocument"
        "401":
          $ref: "#/responses/401WithDocument"
        "429":
          $ref: "#/responses/429WithDocument"
        "500":
          $ref: "#/responses/500WithDocument"
        "503":
          $ref: "#/responses/503WithDocument"
      security:
        - oauth2:
            - identity.write
      summary: Update the logged-in user's favorite station(s)
      tags:
        - identity
  /v2/user:
    delete:
      description: Use with caution as some steps are irreverisble. Initiates the user account deletion process, including removal of all user PII and account access.
      operationId: deleteUser
      parameters:
        - $ref: "#/parameters/Authorization"
      responses:
        "200":
          $ref: "#/responses/IdentitySuccess"
        "401":
          $ref: "#/responses/401WithDocument"
        "500":
          $ref: "#/responses/500WithDocument"
        "503":
          $ref: "#/responses/503WithDocument"
      security:
        - oauth2:
            - identity.write
      summary: Delete the user's account
      tags:
        - identity
    get:
      description: After a successful login, the client should send a `GET` call approximately once an hour to refresh the user data.
      operationId: getUser
      parameters:
        - $ref: "#/parameters/Authorization"
      responses:
        "200":
          $ref: "#/responses/IdentitySuccess"
        "401":
          $ref: "#/responses/401WithDocument"
        "429":
          $ref: "#/responses/429WithDocument"
        "500":
          $ref: "#/responses/500WithDocument"
        "503":
          $ref: "#/responses/503WithDocument"
      security:
        - oauth2:
            - identity.readonly
      summary: Get the latest state information about the logged-in user
      tags:
        - identity
  /v2/user/inherit:
    post:
      description: |-
        This can and should only be used by clients who have access to the `temporary_user` grant type.
            Third-party developers do not have access to this grant type by default, and will not need this endpoint.
      operationId: inheritFromTempUser
      parameters:
        - $ref: "#/parameters/Authorization"
        - description: The temporary user's ID before the user registered or logged in
          in: query
          name: temp_user
          required: true
          type: integer
      responses:
        "202":
          $ref: "#/responses/IdentitySuccess"
        "400":
          $ref: "#/responses/400WithDocument"
        "429":
          $ref: "#/responses/429WithDocument"
        "500":
          $ref: "#/responses/500WithDocument"
        "503":
          $ref: "#/responses/503WithDocument"
      security:
        - oauth2:
            - identity.write
      summary: Copy listening data from a temporary user account to the logged-in user's account
      tags:
        - identity
definitions:
  AbstractCDocLink:
    allOf:
      - $ref: "#/definitions/AbstractLink"
      - properties:
          content-type:
            description: The MIME type of the response of this link
            type: string
        required:
          - content-type
  AbstractLink:
    properties:
      href:
        description: The link to be followed
        format: uri
        type: string
    required:
      - href
  Affiliation:
    description: A program (aggregation) that a given user has shown an affiliation with
    properties:
      daysSinceLastListen:
        description: The number of days since a user last listened to a story from this aggregation. Absent if user never listened to the aggregation.
        format: int32
        type: integer
      following:
        default: false
        description: Whether or not the user is following the aggregation. When changing affiliation status, the client is expected to toggle this value and then send the entire object back.
        type: boolean
      href:
        description: A link to more details about the program from the NPR Story API
        type: string
      id:
        description: A unique identifier for the aggregation (program)
        type: string
      notif_following:
        description: The topic in Firebase Cloud Messaging to which the device should subscribe if it supports notifications and the user wants notifications about the podcasts they follow.
        items:
          type: string
        type: array
      notif_rated:
        description: The topic in Firebase Cloud Messaging to which the device should subscribe if it supports notifications and the user wants notifications about the podcasts they have highly rated.
        items:
          type: string
        type: array
      rating:
        description: The user's average rating for this affiliation on a scale of 0-1. Absent if user never listened to the aggregation.
        format: float
        type: number
      title:
        description: The title for the aggregation (program)
        type: string
    required:
      - id
      - href
      - following
  Algolia:
    description: Parameters for querying the Algolia Search SDK for content
    properties:
      apiKey:
        description: A search API key for this user
        type: string
    required:
      - apiKey
  Cohort:
    description: An experimental grouping for User Experience A/B Testing
    properties:
      id:
        description: A short ID for this cohort; ignored on a PUT
        type: string
      name:
        description: A text string identifying the cohort, useful for metrics; ignored on a PUT
        type: string
      public:
        description: For internal use only; represents the current configuration file being used by the Listening Service
        type: string
      test:
        description: For internal use only; represents the test configuration file being used by the Listening Service
        type: string
    required:
      - id
      - name
  CollectionDocument:
    description: Base Collection.Doc+JSON output
    properties:
      attributes:
        type: object
      errors:
        description: A list of encountered errors, ignored on POST, PUT
        items:
          type: object
        type: array
      href:
        description: A URL representation of the resource; should generally be ignored by clients unless noted otherwise
        type: string
      items:
        items:
          type: object
        type: array
      links:
        type: object
      version:
        default: "1.0"
        description: The version of the Collection.Doc+JSON spec being used
        type: string
    required:
      - version
      - href
      - attributes
      - items
      - links
      - errors
  Error:
    description: A serialized version of any error encountered when processing this request
    properties:
      code:
        description: The error code
        format: int32
        type: integer
      debug:
        description: Additional debug information if debug mode is turned on
        type: string
      text:
        description: The error description
        type: string
    required:
      - code
  ErrorDocument:
    allOf:
      - $ref: "#/definitions/CollectionDocument"
      - properties:
          attributes:
            description: Ignore; will be empty for errors
            type: object
          errors:
            description: A list of encountered errors, ignored on POST, PUT
            items:
              $ref: "#/definitions/Error"
            type: array
          items:
            description: Ignore; will be empty for errors
            items:
              type: object
            type: array
          links:
            description: Ignore; will be empty for errors
            type: object
    description: A Collection.doc+JSON representation of an error result from an API call
  Organization:
    description: A station that a user has an affiliation with
    properties:
      call:
        description: Station call letters
        type: string
      city:
        description: A short description of the station's main market city
        type: string
      displayName:
        description: A short displayable text field for the end user, strictly text; ignored on PUT
        type: string
      donationUrl:
        description: Station donation page URL
        type: string
      id:
        description: Some unique identifier for the organization for the user
        type: string
      logo:
        description: Station logo image url
        type: string
      notif_org:
        description: The topic in Firebase Cloud Messaging to which the device should subscribe if it supports notifications and the user wants notifications about their localized station.
        items:
          type: string
        type: array
      serviceId:
        description: Some unique identifier for the user's organization's primary service, or null if the org has no services
        type: string
      smallLogo:
        description: Station logo image url
        type: string
    required:
      - id
      - displayName
      - call
      - city
  UserData:
    description: Object; see description of a user object below
    properties:
      affiliations:
        description: Program(s) that the user has positively interacted with
        items:
          $ref: "#/definitions/Affiliation"
        type: array
      algolia:
        description: Use this information to search Algolia for stories
        items:
          $ref: "#/definitions/Algolia"
        type: array
      cohort:
        $ref: "#/definitions/Cohort"
        description: Experimental groupings for User Experience A/B Testing
      email:
        description: The user's email address
        type: string
      firstName:
        description: The user's first name
        type: string
      id:
        description: Some unique identifier for the user
        type: string
      lastName:
        description: The user's last name
        type: string
      organizations:
        description: User's chosen NPR Member Station(s)
        items:
          $ref: "#/definitions/Organization"
        type: array
      totalListeningTime:
        description: Internal use only. User's total listening time across all platforms.
        type: string
    required:
      - id
      - cohort
      - organizations
      - algolia
  UserDocument:
    allOf:
      - $ref: "#/definitions/CollectionDocument"
      - properties:
          attributes:
            $ref: "#/definitions/UserData"
            description: Object; see description of a user object below
          items:
            description: Not used, ignored on a PUT
            items:
              type: object
            type: array
          links:
            description: A list of links, not used by the Identity Service; ignored on a PUT
            type: object
