swagger: "2.0"
schemes:
  - https
host: station.api.npr.org
info:
  contact:
    email: NPROneEnterprise@npr.org
    name: NPR One Enterprise Team
    url: https://dev.npr.org
    x-twitter: NPR
  description: Allows clients to look up NPR member station information
  termsOfService: https://dev.npr.org/guide/prerequisites/terms-of-use
  title: NPR Station Finder Service
  version: "3"
  x-apisguru-categories:
    - entertainment
  x-logo:
    url: https://twitter.com/NPR/profile_image?size=original
  x-origin:
    - format: swagger
      url: https://station.api.npr.org/v3/swagger.json
      version: "2.0"
  x-providerName: npr.org
  x-serviceName: station-finder
externalDocs:
  description: Learn more at the NPR One Developer Center
  url: https://dev.npr.org/guide/services/station-finder
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"
paths:
  /v3/stations:
    get:
      description: |-
        This endpoint has two main use cases:

        - If no query parameters passed in, it returns a list of stations that are geographically closest to the calling client (based on GeoIP information)
        - If one or more query parameters are passed in, it performs a search of NPR stations that match those search criteria (not taking into account the client's physical location)

        Clients wanting to implement a 'Change Station' UI should use this endpoint to power their search. In most cases, you'll want to build a search interface that uses one of the 3 provided schemas: `lat` and `lon` (using e.g. the HTML5 Geolocation API), `city` and `state`, _or_ the generic `q` query which can accept a station name, call letters, network name, or zip code. Technically speaking, `q` can also take in either a city name or a state name, but using the `city` and `state` parameters together will yield more accurate geographic search results than `q={cityName}`.

        The `lat` and `lon` query parameters should always be passed in together (otherwise the API will return a 400 error), and if included in the query, they will take precedence over any other search criteria; that is, `lat` and `lon` will do a purely geographic search and not take into account `q`, `city` or `state`.

        Similarly, `city` and/or `state` will take precedence over (and ignore) `q`.

        If clients want to be able to offer multiple types of searches (e.g. 'Search for a station name, city or zipcode') using a *single* search input form, `q` should be used. But again, be aware that using `city` and `state` together will yield more accurate search results than `q={cityName}`.
      operationId: searchStations
      parameters:
        - $ref: "#/parameters/Authorization"
        - description: Search terms to search on; can be a station name, network name, call letters, or zipcode
          in: query
          name: q
          required: false
          type: string
        - description: A city to look for stations from; intended to be paired with `state`
          in: query
          name: city
          pattern: ^[A-Za-z '\.]+$
          required: false
          type: string
        - description: A state to look for stations from (using the 2-letter abbreviation); intended to be paired with `city`
          in: query
          name: state
          pattern: ^[A-Z]{2}$
          required: false
          type: string
        - description: A latitude value from a geographic coordinate system; only works if paired with `lon`
          format: float
          in: query
          name: lat
          required: false
          type: number
        - description: A longitude value from a geographic coordinate system; only works if paired with `lat`
          format: float
          in: query
          name: lon
          required: false
          type: number
      responses:
        "200":
          description: A list of one or more stations matching the search query
          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/StationListDocument"
        "400":
          $ref: "#/responses/400WithDocument"
        "401":
          $ref: "#/responses/401WithDocument"
        "429":
          $ref: "#/responses/429WithDocument"
        "500":
          $ref: "#/responses/500WithDocument"
        "503":
          $ref: "#/responses/503WithDocument"
      summary: List stations close to you or filter by search criteria
      tags:
        - stationfinder
  "/v3/stations/{stationId}":
    get:
      description: |-
        This endpoint retrieves information about a given station, based on its numeric ID, which is consistent across all of NPR's APIs.

        A typical use case for this data is for clients who want to create a dropdown menu, modal/pop-up or dedicated page displaying more information about the station the client is localized to, including, for example, links to the station's homepage and donation (pledge) page.
      operationId: getStationById
      parameters:
        - $ref: "#/parameters/Authorization"
        - description: The numeric ID of a station
          format: int64
          in: path
          name: stationId
          required: true
          type: integer
      responses:
        "200":
          description: A document describing the station with the given ID
          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/StationDocument"
        "400":
          $ref: "#/responses/400WithDocument"
        "401":
          $ref: "#/responses/401WithDocument"
        "404":
          $ref: "#/responses/404WithDocument"
        "429":
          $ref: "#/responses/429WithDocument"
        "500":
          $ref: "#/responses/500WithDocument"
        "503":
          $ref: "#/responses/503WithDocument"
      summary: Retrieve metadata for the station with the given numeric ID
      tags:
        - stationfinder
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
  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
  StationBrandData:
    description: An associative array of brand-related metadata for this station
    properties:
      band:
        default: FM
        description: The subsection of the radio spectrum -- 'AM' or 'FM' -- where this station can be heard
        enum:
          - FM
          - AM
        type: string
      call:
        description: The three-to-four-letter identifying code for this station. Please use this with caution; most stations prefer to be identified by their `name` in client applications instead of `call`.
        pattern: ^(W|K)[A-Z]{2,3}$
        type: string
      frequency:
        description: Where on the radio dial the station can be heard. If the `band` is AM, the frequency will be between 540 and 1600. If the `band` is FM, the frequency will be between 87.8 and 108.0.
        pattern: ^\d{2,3}\.?\d$
        type: string
      marketCity:
        description: The city that the station is most closely associated with. This may or may not be the city the station is licensed in and it may or may not be the city that the station or the station's antenna is located in.
        pattern: ^[A-Za-z '\.]+$
        type: string
      marketState:
        description: The state that the station is most closely associated with. This may or may not be the state the station is licensed in and it may or may not be the state that the station or the station's antenna is located in.
        pattern: ^[A-Z]{2}$
        type: string
      name:
        description: The display name for the station. In most cases, this will be the same as `call` letters combined with band. When returning networks, it will return the network name (e.g. Minnesota Public Radio).
        type: string
      tagline:
        default: ""
        description: A short text-logo for the station
        type: string
    required:
      - name
      - tagline
      - marketCity
      - marketState
  StationBrandLink:
    allOf:
      - $ref: "#/definitions/AbstractCDocLink"
      - properties:
          rel:
            default: homepage
            description: A short string identifier describing the way the way the link relates to the document
            enum:
              - homepage
              - logo
              - small-logo
              - hello-id-audio
              - station-message-audio
              - twitter
              - facebook
            type: string
        required:
          - rel
    description: A link to a web page, logo, or audio file related to the branding of the station
  StationData:
    properties:
      brand:
        $ref: "#/definitions/StationBrandData"
        description: An associative array of brand-related metadata for this station
      eligibility:
        $ref: "#/definitions/StationEligibilityData"
        description: An associative array of eligibility-related metadata for this station
      guid:
        description: The system's internal unique identifier for a station, not typically used by other APIs or consumers
        pattern: ^[0-9a-f]{32}$
        type: string
      network:
        $ref: "#/definitions/StationNetworkData"
        description: Metadata about the network, if this station is part of a network
      newscast:
        $ref: "#/definitions/StationNewscastData"
        description: Metadata about the newscast for this station; this is handled internally by other microservices such as the NPR One Listening Service, so this data should typically not be used by consumers
      orgId:
        description: The system's unique ID for this station, used across NPR One Microservices and NPR's other APIs
        pattern: ^\d{1,4}$
        type: string
    required:
      - orgId
      - guid
      - brand
      - eligibility
      - network
  StationDocument:
    allOf:
      - $ref: "#/definitions/CollectionDocument"
      - properties:
          attributes:
            $ref: "#/definitions/StationData"
            description: The metadata for the station
          items:
            description: Not used
            items:
              type: object
            type: array
          links:
            $ref: "#/definitions/StationLinks"
            description: A list of links consisting of logos, audio files, and external URLs related to this station.
  StationDonationLink:
    allOf:
      - $ref: "#/definitions/StationLink"
      - properties:
          typeId:
            default: "4"
            description: An identifier for the type of link; '4' denotes a generic pledge page, while '27' is an NPR One-specific pledge page
            enum:
              - "4"
              - "27"
              - "28"
              - "29"
            type: string
        required:
          - typeId
    description: A link to a pledge page for the station
  StationEligibilityData:
    description: An associative array of eligibility-related metadata for this station
    properties:
      format:
        default: Public Radio
        description: The format of the programming on this station
        type: string
      localization:
        default: Show everywhere
        description: Whether or not this station should be shown in search for news context, any context or no context
        type: string
      musicOnly:
        default: false
        description: Whether or not this station only plays music.  Deprecated.
        type: boolean
      nprOne:
        default: true
        description: Whether or not this station is considered an NPR One station
        type: boolean
      status:
        default: "1"
        description: The status of the station within NPR's system, not typically used by consumers
        enum:
          - "1"
          - "9"
          - "10"
          - "12"
          - "15"
        type: string
    required:
      - nprOne
      - format
      - musicOnly
      - status
  StationLink:
    allOf:
      - $ref: "#/definitions/AbstractLink"
      - properties:
          guid:
            description: The system's internal unique identifier for a link, not typically used by consumers
            pattern: ^[0-9a-f]{32}$
            type: string
          title:
            default: ""
            description: The link text, provided by the station, for the URL
            type: string
          typeName:
            description: The semantic name corresponding to the `typeId`
            type: string
        required:
          - typeName
    description: A link related to the station
  StationLinks:
    properties:
      brand:
        description: One or more links to a web page for the station
        items:
          $ref: "#/definitions/StationBrandLink"
        type: array
      donation:
        description: One or more links to audio files related to this station
        items:
          $ref: "#/definitions/StationDonationLink"
        type: array
      podcasts:
        description: One or more links to podcasts related to this station
        items:
          $ref: "#/definitions/StationPodcastsLink"
        type: array
      related:
        description: One or more links to miscellaneous related content for the station; these typically are not present, and clients should generally not need to use any of these
        items:
          $ref: "#/definitions/StationRelatedLink"
        type: array
      streams:
        description: One or more links to audio streams related to the station
        items:
          $ref: "#/definitions/StationStreamsLink"
        type: array
    required:
      - brand
  StationListDocument:
    allOf:
      - $ref: "#/definitions/CollectionDocument"
      - properties:
          attributes:
            $ref: "#/definitions/StationSearchMetaData"
            description: The metadata for the search itself
          items:
            description: A list of stations
            items:
              $ref: "#/definitions/StationDocument"
            type: array
          links:
            description: Not used
            type: object
    description: A collection of stations close to you or filtered by search criteria
  StationNetworkData:
    description: Metadata about the network, if this station is part of a network
    properties:
      currentOrgId:
        description: The current station being viewed. Client applications should generally ignore this field.
        pattern: ^\d{1,4}$
        type: string
      tier1:
        $ref: "#/definitions/StationNetworkTierOneData"
        description: The top-level organization, if this station is part of a network
      usesInheritance:
        description: Whether or not the current station inherits from a parent organization, also referred to as a network
        type: boolean
    required:
      - currentOrgId
      - usesInheritance
  StationNetworkTierOneData:
    description: Metadata about the top-level organization in the network, if this station is part of a network
    properties:
      id:
        description: The unique identifier of the top-level organization in the network
        pattern: ^\d{1,4}$
        type: string
      name:
        description: The display name for the top-level organization in the network
        type: string
      status:
        default: "10"
        description: The status of the top-level organization within NPR's system, not typically used by consumers
        enum:
          - "1"
          - "9"
          - "10"
          - "12"
          - "15"
        type: string
      tier2:
        description: One or more stations that are hierarchical children of this organization
        items:
          $ref: "#/definitions/StationNetworkTierTwoData"
        type: array
      usesInheritance:
        description: Whether or not this station inherits from a parent organization, also referred to as a network
        type: boolean
    required:
      - id
      - name
      - usesInheritance
  StationNetworkTierThreeData:
    description: Metadata about a tier 3 organization in the network, if this station is part of a network
    properties:
      id:
        description: The unique identifier of a tier 3 organization in the network
        pattern: ^\d{1,4}$
        type: string
      name:
        description: The display name for a tier 3 organization in the network
        type: string
      usesInheritance:
        description: Whether or not this station inherits from a parent organization, also referred to as a network
        type: boolean
    required:
      - id
      - name
      - usesInheritance
  StationNetworkTierTwoData:
    description: Metadata about a tier 2 organization in the network, if this station is part of a network
    properties:
      id:
        description: The unique identifier of a tier 2 organization in the network
        pattern: ^\d{1,4}$
        type: string
      name:
        description: The display name for a tier 2 organization in the network
        type: string
      tier3:
        description: One or more stations that are hierarchical children of this organization
        items:
          $ref: "#/definitions/StationNetworkTierThreeData"
        type: array
      usesInheritance:
        description: Whether or not this station inherits from a parent organization, also referred to as a network
        type: boolean
    required:
      - id
      - name
      - usesInheritance
  StationNewscastData:
    description: Metadata about the newscast for this station; newscasts are handled internally by other microservices such as the NPR One Listening Service, so this data should typically not be used by consumers
    properties:
      id:
        description: The ID of the newscast that should be played for this station; this is handled internally by other microservices such as the NPR One Listening Service, so this field should typically not be used by consumers
        pattern: ^\d{1,4}$
        type: string
      recency:
        description: How often the newscast should be played, in minutes; a value of `null` implies no information is available, and sensible defaults should be used
        format: int32
        type: integer
    required:
      - id
      - recency
  StationPodcastsLink:
    allOf:
      - $ref: "#/definitions/StationLink"
      - properties:
          typeId:
            default: "9"
            description: An identifier for the type of link
            enum:
              - "9"
            type: string
        required:
          - typeId
    description: A link to an audio podcast or podcast feed related to the station
  StationRelatedLink:
    allOf:
      - $ref: "#/definitions/StationLink"
      - properties:
          typeId:
            description: An identifier for the type of link
            type: string
        required:
          - typeId
    description: A link to miscellaneous related content for the station; these typically are not present, and clients should generally not need to use these
  StationSearchMetaData:
    properties:
      city:
        description: The city searched for in the original request
        type: string
      countryCode:
        description: The country where the original request originated, as determined by geolocation. The countryCode is in ISO 3166-1 numeric format
        type: string
      lat:
        description: The latitude parameter used in the original request
        format: float
        type: number
      lon:
        description: The longitude parameter in the original request
        format: float
        type: number
      query:
        description: The search terms used in the original request
        type: string
      state:
        description: The state searched for in the original request
        type: string
  StationStreamsLink:
    allOf:
      - $ref: "#/definitions/StationLink"
      - properties:
          isPrimaryStream:
            default: true
            description: Whether or not this stream is considered the station's primary stream
            type: boolean
          typeId:
            default: "10"
            description: An identifier for the type of stream
            enum:
              - "10"
              - "11"
              - "12"
              - "13"
            type: string
        required:
          - typeId
    description: A link to an audio stream related to the station
