GraphQL API: Playback
Set a source to start playback
To start playback a source needs to be set for your device. If it was successful, the metadata of the source will be returned and can then be used for playback.
Listeners with a free subscription can only play podcasts and stations.  The first time a station (ST) source is desired, it should be set on a station factory (SF) as stations are listener specific and new listeners will not have any stations. Setting a station factory source will return the listener the specific station which can be used in subsequent playback setSource mutations.  Read more about stations vs station factories here.
Listeners with a Premium subscription can play sources on demand and are not limited to stations. They can also start playback on an album, track or playlist.
Some things to consider:
- Station (ST) sources can only be set if the station belongs to the user.
 - Audio URLs returned are short-lived.
 - Sources have limited lifetimes.
 - Sources are set for the device specified, not for your application, so it is possible to handle multiple device logins for your application.
 
To trigger audio ads for testing purposes, an argument called testMode has been made available. You can add this with a value of "audio".
Mutation
mutation {
  playback {
    setSource(deviceUuid: "deviceXYZ", sourceId: "SF:16722:1360") {
      id
      type
      current {
        __typename
        index
        ... on TrackItem {
          trackToken
          audioUrl
          interactions
          track {
            duration
            art {
              url(size: WIDTH_130)
            }
            artist {
              name
            }
          }
        }
        ... on AudioAdItem {
          audioUrl
          interactions
        }
      }
    }
  }
}
    * Add your OAuth bearer token to the Authorization header
curl 'https://ce.pandora.com/api/v1/graphql/graphql' \
  -H 'Authorization: Bearer ' \
  -H 'Content-Type: application/json' \
  -d '{"operationName":null,"variables":{},"query":"mutation {  playback { setSource(deviceUuid: \"deviceXYZ\", sourceId: \"SF:16722:1360\") { id type current { ... on TrackItem { index trackToken audioUrl interactions track { duration art { url(size: WIDTH_130) } artist { name } } } } }  }}"}'
    Response
{
  "data": {
    "playback": {
      "setSource": {
        "id": "ST:0:4326813985954039828",
        "type": "ST",
        "current": {
          "index": 1,
          "trackToken": "P8q7bU-LSkOkouJlpPz4KYHlxV0EZ2D7J4_lo0MAQJXK-rq7vhAbsIZMs7AJAVLagIB9JlMb2sEBFNQuSrSvuODO4yO6Rm66e",
          "audioUrl": "https://t3-4.p-cdn.us/access/4801370763899556419?version=5&lid=1375438868&token=aj/zHujl4ifh/LgQgQjBrYk0QWS98NfLQPgGh6H2KQZDd97PytZk/aTIymR5MQjFP3UVQ74x4Gxj3G/6gfXg5hUiJ6AOVs+w+CVC67x8EFpHxEFl1gv9snQLu7kMHiEMeCqxAWkZN80s17JxfkIO3C76IlVnEnooc7kEtltINUcJatGdUW1QUnL572F6Xj5Ajty1YB4b2l1Jlnms0Yx3ZX1wTycc97DVzl3IMmRsOJQ30+jKMzVCNQfVlEcRY4ZoHm05jqYTftQE78BC1Mf/WYiceJTXaIv4UFMZmg+9LhtPyQfJf/+qiUuZFRDEfvGqScdug/WNnrLqedwiIYR9uQ==",
          "interactions": [
            "SKIP",
            "REPLAY",
            "THUMB"
          ],
          "track": {
            "duration": 157,
            "art": {
              "url": "https://dyn-images.p-cdn.com/?l=images%2Fpublic%2Fint%2F4%2F2%2F5%2F9%2F081227889524%3Acover()&w=150&h=150"
            },
            "artist": {
              "name": "The Cure"
            }
          }
        }
      }
    }
  }
}
Playing non-explicit content
When playing source that have both explicit and non-explicit content.  To start playback with only non-explicit content, you can add the forceNonExplicit parameter with the value set to true in the setSource query:
Mutation
mutation {
  playback {
    setSource(deviceUuid:"deviceXYZ", sourceId:"AL:666352", forceNonExplicit: true){
      id
      current {
        __typename
        ... on TrackItem {
          track {
            name
          }
        }
      }
    }
  }
}
    * Add your OAuth bearer token to the Authorization header
curl 'https://ce.pandora.com/api/v1/graphql/graphql' \
  -H 'Authorization: Bearer ' \
  -H 'Content-Type: application/json' \
  -d '{"operationName":null,"variables":{},"query":"mutation {  playback { setSource(deviceUuid: \"deviceXYZ\", sourceId: \"AL:666352\", forceNonExplicit: true) { id current { ... on TrackItem { track { name } } } }  }}"}'
    Response
{
  "data": {
    "playback": {
      "setSource": {
        "id": "AL:666352",
        "current": {
          "track": {
            "name": "Dreams"
          }
        }
      }
    }
  }
}
If the source requested only contains explicit content, you will get an error:
Mutation
mutation {
  playback {
    setSource(
      deviceUuid: "deviceXYZ"
      sourceId: "TR:2070262"
      forceNonExplicit: true
    ) {
      id
      current {
        __typename
        ... on TrackItem {
          track {
            name
          }
        }
      }
    }
  }
}
    * Add your OAuth bearer token to the Authorization header
curl 'https://ce.pandora.com/api/v1/graphql/graphql' \
  -H 'Authorization: Bearer ' \
  -H 'Content-Type: application/json' \
  -d '{"operationName":null,"variables":{},"query":"mutation {  playback { setSource(deviceUuid: \"deviceXYZ\", sourceId: \"TR:2070262\", forceNonExplicit: true) { id current { ... on TrackItem { track { name } } } }  }}"}'
    Response
{
  "errors": [
    {
      "message": "Source requested with forceNonExplicit had no tracks with a clean version (NO_CLEAN_CONTENT)",
      "locations": [
        {
          "line": 5,
          "column": 7
        }
      ],
      "path": [
        "playback",
        "setSource",
        "current"
      ],
      "extensions": {
        "code": "BAD_USER_INPUT"
      }
    }
  ],
  "data": {
    "playback": {
      "setSource": {
        "id": "TR:2070262",
        "current": null
      }
    }
  }
}