summaryrefslogtreecommitdiff
path: root/json
diff options
context:
space:
mode:
Diffstat (limited to 'json')
-rw-r--r--json/authentication.rst179
-rw-r--r--json/bookmarks.rst157
-rw-r--r--json/errorcodes.rst54
-rw-r--r--json/index.rst79
-rw-r--r--json/methods.rst42
-rw-r--r--json/partners.rst71
-rw-r--r--json/play.rst209
-rw-r--r--json/stations.rst289
8 files changed, 1080 insertions, 0 deletions
diff --git a/json/authentication.rst b/json/authentication.rst
new file mode 100644
index 0000000..67f5879
--- /dev/null
+++ b/json/authentication.rst
@@ -0,0 +1,179 @@
+.. _authentication:
+
+Authentication
+==============
+
+Authentication is divided into two steps: Partner and user login.
+
+.. _auth-partnerLogin:
+
+Partner login
+-------------
+
+:Method: auth.partnerLogin
+
+This request additionally serves as API version validation, time
+synchronization and endpoint detection and *must* be sent over a TLS-encrypted
+link. The POST body however is :ref:`not encrypted <bodyenc>`.
+
+.. csv-table::
+ :header: Name,Type,Description
+
+ username,string,See :ref:`partners`
+ password,string,See :ref:`partners`
+ deviceModel,string,See :ref:`partners`
+ version,string,"Current version number, “5”."
+ includeUrls,boolean,
+ returnDeviceType,boolean,
+ returnUpdatePromptVersions,boolean,
+
+.. code:: json
+
+ {
+ "username": "pandora one",
+ "password": "TVCKIBGS9AO9TSYLNNFUML0743LH82D",
+ "deviceModel": "D01",
+ "version": "5"
+ }
+
+syncTime is used to calculate the server time, see :ref:`synctime`. partnerId
+and authToken are required to procceed with user authentication.
+
+================ ======= ===========
+Name Type Description
+================ ======= ===========
+syncTime string Hex-encoded, encrypted server time. Decrypt with password from :ref:`partners` and skip first four bytes of garbage.
+partnerAuthToken string
+partnerId string
+================ ======= ===========
+
+.. code:: json
+
+ {
+ "stat": "ok",
+ "result": {
+ "syncTime": "6923e263a8c3ac690646146b50065f43",
+ "deviceProperties": {
+ "videoAdRefreshInterval": 900,
+ "videoAdUniqueInterval": 0,
+ "adRefreshInterval": 5,
+ "videoAdStartInterval": 180
+ },
+ "partnerAuthToken": "VAzrFQTtsy3BQ3K+3iqFi0WF5HA63B1nFA",
+ "partnerId": "42",
+ "stationSkipUnit": "hour",
+ "urls": {
+ "autoComplete": "http://autocomplete.pandora.com/search"
+ },
+ "stationSkipLimit": 6
+ }
+ }
+
+==== ============
+Code Description
+==== ============
+1002 INVALID_PARTNER_LOGIN. Invalid partner credentials.
+==== ============
+
+.. _auth-userLogin:
+
+User login
+----------
+
+:Method: auth.userLogin
+
+This request *must* be sent over a TLS-encrypted link. It authenticates the
+Pandora user by sending his username, usually his email address, and password
+as well as the partnerAuthToken obtained by :ref:`auth-partnerLogin`.
+
+.. TODO: Describe device login.
+
+Additional response data can be requested by setting flags listed below.
+
+.. csv-table::
+ :header: Name,Type,Description
+
+ loginType ,string ,“user”
+ username ,string ,Username
+ password ,string ,User’s password
+ partnerAuthToken ,string ,Partner token obtained by :ref:`auth-partnerLogin`
+ returnGenreStations ,boolean ,(optional)
+ returnCapped ,boolean ,return isCapped parameter (optional)
+ includePandoraOneInfo,boolean,(optional)
+ includeDemographics,boolean,(optional)
+ includeAdAttributes,boolean,(optional)
+ returnStationList,boolean,"Return station list, see :ref:`user-getStationList` (optional)"
+ includeStationArtUrl,boolean,(optional)
+ includeStationSeeds,boolean,(optional)
+ includeShuffleInsteadOfQuickMix,boolean,(optional)
+ stationArtSize,string,W130H130(optional)
+ returnCollectTrackLifetimeStats,boolean,(optional)
+ returnIsSubscriber,boolean,(optional)
+ xplatformAdCapable,boolean,(optional)
+ complimentarySponsorSupported,boolean,(optional)
+ includeSubscriptionExpiration,boolean,(optional)
+ returnHasUsedTrial,boolean,(optional)
+ returnUserstate,boolean,(optional)
+ includeAccountMessage,boolean,(optional)
+ includeUserWebname,boolean,(optional)
+ includeListeningHours,boolean,(optional)
+ includeFacebook,boolean,(optional)
+ includeTwitter,boolean,(optional)
+ includeDailySkipLimit,boolean,(optional)
+ includeSkipDelay,boolean,(optional)
+ includeGoogleplay,boolean,(optional)
+ includeShowUserRecommendations,boolean,(optional)
+ includeAdvertiserAttributes,boolean,(optional)
+
+
+.. code:: json
+
+ {
+ "loginType": "user",
+ "username": "user@example.com",
+ "password": "example",
+ "partnerAuthToken": "VAzrFQTtsy3BQ3K+3iqFi0WF5HA63B1nFA",
+ "includePandoraOneInfo":true,
+ "includeAdAttributes":true,
+ "includeSubscriptionExpiration":true,
+ "includeStationArtUrl":true,
+ "returnStationList":true,
+ "returnGenreStations":true,
+ "syncTime": 1335777573
+ }
+
+The returned userAuthToken is used to authenticate access to other API methods.
+
+.. csv-table::
+ :header: Name ,Type ,Description
+
+ isCapped ,boolean ,
+ userAuthToken,string,
+
+.. code:: json
+
+ {
+ "stat": "ok",
+ "result": {
+ "stationCreationAdUrl": "http://ad.doubleclick.net/adx/pand.android/prod.createstation;ag=112;gnd=1;zip=23950;genre=0;model=;app=;OS=;dma=560;clean=0;logon=__LOGON__;tile=1;msa=115;st=VA;co=51117;et=0;mc=0;aa=0;hisp=0;hhi=0;u=l*2jedvn446s7ce!ag*112!gnd*1!zip*23950!dma*560!clean*0!logon*__LOGON__!msa*115!st*VA!co*51117!et*0!mc*0!aa*0!hisp*0!hhi*0!genre*0;sz=320x50;ord=__CACHEBUST__",
+ "hasAudioAds": true,
+ "splashScreenAdUrl": "http://ad.doubleclick.net/pfadx/pand.android/prod.welcome;ag=112;gnd=1;zip=23950;model=;app=;OS=;dma=560;clean=0;hours=1;msa=115;st=VA;co=51117;et=0;mc=0;aa=0;hisp=0;hhi=0;u=l*op4jfgdxmddjk!ag*112!gnd*1!zip*23950!dma*560!clean*0!msa*115!st*VA!co*51117!et*0!mc*0!aa*0!hisp*0!hhi*0!hours*1;sz=320x50;ord=__CACHEBUST__",
+ "videoAdUrl": "http://ad.doubleclick.net/pfadx/pand.android/prod.nowplaying;ag=112;gnd=1;zip=23950;dma=560;clean=0;hours=1;app=;index=__INDEX__;msa=115;st=VA;co=51117;et=0;mc=0;aa=0;hisp=0;hhi=0;u=l*2jedvn446s7ce!ag*112!gnd*1!zip*23950!dma*560!clean*0!index*__INDEX__!msa*115!st*VA!co*51117!et*0!mc*0!aa*0!hisp*0!hhi*0!hours*1;sz=442x188;ord=__CACHEBUST__",
+ "username": "user@example.com",
+ "canListen": true,
+ "nowPlayingAdUrl": "http://ad.doubleclick.net/pfadx/pand.android/prod.nowplaying;ag=112;gnd=1;zip=23950;genre=0;station={4};model=;app=;OS=;dma=560;clean=0;hours=1;artist=;interaction=__INTERACTION__;index=__INDEX__;newUser=__AFTERREG__;logon=__LOGON__;msa=115;st=VA;co=51117;et=0;mc=0;aa=0;hisp=0;hhi=0;u=l*op4jfgdxmddjk!ag*112!gnd*1!zip*23950!station*{4}!dma*560!clean*0!index*__INDEX__!newUser*__AFTERREG__!logon*__LOGON__!msa*115!st*VA!co*51117!et*0!mc*0!aa*0!hisp*0!hhi*0!genre*0!interaction*__INTERACTION__!hours*1;sz=320x50;ord=__CACHEBUST__",
+ "userId": "272772589",
+ "listeningTimeoutMinutes": "180",
+ "maxStationsAllowed": 100,
+ "listeningTimeoutAlertMsgUri": "/mobile/still_listening.vm",
+ "userProfileUrl": "https://www.pandora.com/login?auth_token=XXX&target=%2Fpeople%2FXXX",
+ "minimumAdRefreshInterval": 5,
+ "userAuthToken": "XXX"
+ }
+ }
+
+.. csv-table::
+ :header: Code ,Description
+
+ 1002,Wrong user credentials.
+
diff --git a/json/bookmarks.rst b/json/bookmarks.rst
new file mode 100644
index 0000000..1d826bb
--- /dev/null
+++ b/json/bookmarks.rst
@@ -0,0 +1,157 @@
+Bookmarks
+=========
+
+Users can bookmark artists or songs.
+
+.. _user.getBookmarks:
+
+Retrieve bookmarks
+------------------
+
+:Method: user.getBookmarks
+
+The request has no parameters.
+
+.. code:: json
+
+ {
+ "stat":"ok",
+ "result": {
+ "artists": [
+ {
+ "musicToken": "R130360",
+ "artistName": "Cannabich, Christian",
+ "artUrl": "http://cont-sv5-2.pandora.com/images/public/amz/5/2/9/7/095115137925_500W_488H.jpg",
+ "bookmarkToken": "80982345262345234",
+ "dateCreated": {
+ "nanos": 300000000,
+ "seconds": 22,
+ "year": 112,
+ "month": 4,
+ "hours": 11,
+ "time": 1350566223422,
+ "date": 23,
+ "minutes": 01,
+ "day": 2,
+ "timezoneOffset": 720
+ }
+ }
+ ],
+ "songs": [
+ {
+ "sampleUrl": "http://www.pandora.com/favorites/getSample.jsp?token=32458973245b90287345d0234fc34f8b&allowExplicit=true",
+ "sampleGain": "-7.87",
+ "albumName": "Symphony In G Major",
+ "artistName": "Cannabich, Christian",
+ "musicToken": "S2894329",
+ "dateCreated": {
+ "nanos": 300000000,
+ "seconds": 22,
+ "year": 112,
+ "month": 4,
+ "hours": 11,
+ "time": 1350566223422,
+ "date": 23,
+ "minutes": 01,
+ "day": 2,
+ "timezoneOffset": 720
+ },
+ "artUrl": "http://cont-sv5-2.pandora.com/images/public/amz/5/2/9/7/095115137925_500W_488H.jpg",
+ "bookmarkToken": "290832123432459854",
+ "songName": "London Mozart Players, Christian Cannabich: Symphonies"
+ }
+ ]
+ }
+
+ }
+
+.. _bookmark.addArtistBookmark:
+
+Add artist bookmark
+-------------------
+
+:Method: bookmark.addArtistBookmark
+
+.. csv-table::
+ :header: Name ,Type ,Description
+
+ trackToken,string,
+
+.. code:: json
+
+ {
+ "trackToken": "f17ff6c86c11743fc890808e1a1dd6ff5b1dca1a2e260f7d998ba6e7786dd9941c5dd4b345a1008e86862353da1e6cdc78172b4199240c76",
+ "userAuthToken": "XXX",
+ "syncTime": 1338210690
+ }
+
+.. code:: json
+
+ {
+ "stat": "ok",
+ "result": {
+ "artistName": "Wallis Bird",
+ "dateCreated": {
+ "date": 2,
+ "day": 3,
+ "hours": 7,
+ "minutes": 6,
+ "month": 6,
+ "seconds": 13,
+ "time": 1404309973468,
+ "timezoneOffset": 420,
+ "year": 114
+ },
+ "bookmarkToken": "49854851068341741",
+ "artUrl": "http://cont-dc6-2.pandora.com/images/public/amg/portrait/pic200/drP900/P998/P99805K1QKS.jpg",
+ "musicToken": "R278544"
+ }
+ }
+
+.. _bookmark.addSongBookmark:
+
+Add song bookmark
+-----------------
+
+:Method: bookmark.addSongBookmark
+
+.. csv-table::
+ :header: Name ,Type ,Description
+
+ trackToken ,string ,
+
+.. code:: json
+
+ {
+ "trackToken": "f17ff6c86c11743fc890808e1a1dd6ff5b1dca1a2e260f7d998ba6e7786dd9941c5dd4b345a1008e86862353da1e6cdc78172b4199240c76",
+ "userAuthToken": "XXX",
+ "syncTime": 1338210690
+ }
+
+.. code:: json
+
+ {
+ "stat": "ok",
+ "result": {
+ "sampleGain": "1.96",
+ "musicToken": "S1143982",
+ "bookmarkToken": "200207779061968365",
+ "sampleUrl": "http://www.pandora.com/favorites/getSample.jsp?token=a74b4f7551e3e174425ba2910f7abf8b&allowExplicit=true",
+ "albumName": "The 5th Exotic",
+ "songName": "The 5th Exotic",
+ "artUrl": "http://cont-sjl-1.pandora.com/images/public/amz/9/4/5/2/800002549_500W_500H.jpg",
+ "dateCreated": {
+ "date": 28,
+ "day": 1,
+ "hours": 6,
+ "minutes": 11,
+ "month": 4,
+ "seconds": 31,
+ "time": 1338210691404,
+ "timezoneOffset": 420,
+ "year": 112
+ },
+ "artistName": "Quantic"
+ }
+ }
+
diff --git a/json/errorcodes.rst b/json/errorcodes.rst
new file mode 100644
index 0000000..edd14bd
--- /dev/null
+++ b/json/errorcodes.rst
@@ -0,0 +1,54 @@
+List of error codes
+===================
+
+These error codes can be returned by all methods:
+
+==== ============
+Code Description
+==== ============
+0 Internal error. It can denote that your account has been temporarily blocked due to having too frequent station.getPlaylist calls.
+1 MAINTENANCE_MODE
+2 URL_PARAM_MISSING_METHOD
+3 URL_PARAM_MISSING_AUTH_TOKEN
+4 URL_PARAM_MISSING_PARTNER_ID
+5 URL_PARAM_MISSING_USER_ID
+6 SECURE_PROTOCOL_REQUIRED
+7 CERTIFICATE_REQUIRED
+8 PARAMETER_TYPE_MISMATCH
+9 PARAMETER_MISSING
+10 PARAMETER_VALUE_INVALID
+11 API_VERSION_NOT_SUPPORTED
+12 LICENSING_RESTRICTIONS. Pandora not available in this country.
+13 INSUFFICIENT_CONNECTIVITY. Bad sync time?
+14 Unknown method name?
+15 Wrong protocol (http/https)?
+1000 READ_ONLY_MODE
+1001 INVALID_AUTH_TOKEN. Occurs once a user auth token expires.
+1002 INVALID_PARTNER_LOGIN. auth.partnerLogin auth.userLogin. Can also occur for a user login.
+1003 LISTENER_NOT_AUTHORIZED station.getPlaylist Pandora One Subscription or Trial Expired. Possibly account suspended?
+1004 USER_NOT_AUTHORIZED User not authorized to perform action
+1005 MAX_STATIONS_REACHED Station limit reached
+1006 STATION_DOES_NOT_EXIST Station does not exist
+1007 COMPLIMENTARY_PERIOD_ALREADY_IN_USE
+1008 CALL_NOT_ALLOWED station.addFeedback Returned when attempting to add feedback to shared station
+1009 DEVICE_NOT_FOUND
+1010 PARTNER_NOT_AUTHORIZED
+1011 INVALID_USERNAME
+1012 INVALID_PASSWORD
+1013 USERNAME_ALREADY_EXISTS
+1014 DEVICE_ALREADY_ASSOCIATED_TO_ACCOUNT
+1015 UPGRADE_DEVICE_MODEL_INVALID
+1018 EXPLICIT_PIN_INCORRECT
+1020 EXPLICIT_PIN_MALFORMED
+1023 DEVICE_MODEL_INVALID
+1024 ZIP_CODE_INVALID
+1025 BIRTH_YEAR_INVALID
+1026 BIRTH_YEAR_TOO_YOUNG
+1027 INVALID_COUNTRY_CODE
+1027 INVALID_GENDER
+1034 DEVICE_DISABLED
+1035 DAILY_TRIAL_LIMIT_REACHED
+1036 INVALID_SPONSOR
+1037 USER_ALREADY_USED_TRIAL
+==== ============
+
diff --git a/json/index.rst b/json/index.rst
new file mode 100644
index 0000000..48edc1e
--- /dev/null
+++ b/json/index.rst
@@ -0,0 +1,79 @@
+JSON API v5
+===========
+
+The current JSON API version is 5. Two different endpoints are available:
+
+- http://tuner.pandora.com/services/json/
+- https://tuner.pandora.com/services/json/
+
+- http://internal-tuner.pandora.com/services/json/
+- https://internal-tuner.pandora.com/services/json/
+
+.. _bodyenc:
+
+Unless noted otherwise JSON-encoded requests sent by the client within the HTTP
+POST body are encrypted using Blowfish ECB and converted to hexadecimal
+notation.
+
+These URL parameters must be appended to the endpoint above if available:
+
+========== ===========
+Name Description
+========== ===========
+method Method name
+auth_token User auth token if available, partner auth token or empty if neither is known yet.
+partner_id Partner id obtained by :ref:`auth-partnerLogin` or empty
+user_id User id as obtained by :ref:`auth-userLogin` or empty
+========== ===========
+
+For instance when calling :ref:`auth-userLogin` two parameters are known:
+method and partner_id. The URL in this case would be
+``http://tuner.pandora.com/services/json/?method=auth.userLogin&partner_id=123``.
+Make sure you URL encode the parameter’s values.
+
+The following values must be present in every JSON request object (if available):
+
+.. _synctime:
+
+============= ====== ===========
+Name Type Description
+============= ====== ===========
+userAuthToken string User auth token, see :ref:`auth-userLogin`
+syncTime int Synchonized time. Calculation: current time + (time of :ref:`auth-partnerLogin` request – syncTime from :ref:`auth-partnerLogin` response). This is a protection against replay-attacks.
+============= ====== ===========
+
+Every response includes the key ``stat`` which indicates success (``ok``) or
+failure (``fail``) of the resquest. Failed requests contain an error code and
+message whereas successful requests carry actual response data in the key
+``result``:
+
+.. code:: json
+
+ {
+ "stat": "ok",
+ "result": {
+ }
+ }
+
+.. code:: json
+
+ {
+ "stat": "fail",
+ "message": "An unexpected error occurred",
+ "code": 1008
+ }
+
+.. toctree::
+
+ authentication
+ stations
+ play
+ bookmarks
+ methods
+ errorcodes
+
+.. toctree::
+ :hidden:
+
+ partners
+
diff --git a/json/methods.rst b/json/methods.rst
new file mode 100644
index 0000000..f5b7cf5
--- /dev/null
+++ b/json/methods.rst
@@ -0,0 +1,42 @@
+.. _methods:
+
+List of methods
+===============
+
+- :ref:`auth.getAdMetadata <auth-getAdMetadata>`
+- :ref:`auth.partnerLogin <auth-partnerLogin>`
+- :ref:`auth.userLogin <auth-userLogin>`
+- :ref:`bookmark.addArtistBookmark <bookmark-addArtistBookmark>`
+- :ref:`bookmark.addSongBookmark <bookmark-addSongBookmark>`
+- :ref:`bookmark.deleteArtistBookmark <bookmark-deleteArtistBookmark>`
+- :ref:`bookmark.deleteSongBookmark <bookmark-deleteSongBookmark>`
+- :ref:`music.search <music-search>`
+- :ref:`music.shareMusic <music-shareMusic>`
+- :ref:`station.addFeedback <station-addFeedback>`
+- :ref:`station.addMusic <station-addMusic>`
+- :ref:`station.createStation <station-createStation>`
+- :ref:`station.deleteFeedback <station-deleteFeedback>`
+- :ref:`station.deleteMusic <station-deleteMusic>`
+- :ref:`station.deleteStation <station-deleteStation>`
+- :ref:`station.getGenreStations <station-getGenreStations>`
+- :ref:`station.getGenreStationsChecksum <station-getGenreStationsChecksum>`
+- :ref:`station.getPlaylist <station-getPlaylist>`
+- :ref:`station.getStation <station-getStation>`
+- :ref:`station.shareStation <station-shareStation>`
+- :ref:`station.renameStation <station-renameStation>`
+- :ref:`station.transformSharedStation <station-transformSharedStation>`
+- :ref:`test.echo <test-echo>`
+- :ref:`track.explainTrack <track-explainTrack>`
+- :ref:`user.acknowledgeSubscriptionExpiration <user-acknowledgeSubscriptionExpiration>`
+- :ref:`user.associateDevice <user-associateDevice>`
+- :ref:`user.canSubscribe <user-canSubscribe>`
+- :ref:`user.createUser <user-createUser>`
+- :ref:`user.emailPassword <user-emailPassword>`
+- :ref:`user.getBookmarks <user-getBookmarks>`
+- :ref:`user.getStationList <user-getStationList>`
+- :ref:`user.getStationListChecksum <user-getStationListChecksum>`
+- :ref:`user.purchaseItunesSubscription <user-purchaseItunesSubscription>`
+- :ref:`user.setQuickMix <user-setQuickMix>`
+- :ref:`user.sleepSong <user-sleepSong>`
+- :ref:`user.startComplimentaryTrial <user-startComplimentaryTrial>`
+
diff --git a/json/partners.rst b/json/partners.rst
new file mode 100644
index 0000000..a759d41
--- /dev/null
+++ b/json/partners.rst
@@ -0,0 +1,71 @@
+.. _partners:
+
+Partner passwords
+=================
+
+Passwords depend on the API entry point used.
+
+tuner.pandora.com
+-----------------
+
+Android
+^^^^^^^
+
+:username: android
+:password: ``AC7IBG09A3DTSYM4R41UJWL07VLN8JI7``
+:deviceId: android-generic
+:decrpyt password: ``R=U!LH$O2B#``
+:encrypt password: ``6#26FRL$ZWD``
+
+iOS
+^^^
+
+:username: iphone
+:password: ``P2E4FC0EAD3*878N92B2CDp34I0B1@388137C``
+:deviceId: IP01
+:Decrypt password: ``20zE1E47BE57$51``
+:Encrypt password: ``721^26xE22776``
+
+Palm
+^^^^
+
+:Username: palm
+:Password: ``IUC7IBG09A3JTSYM4N11UJWL07VLH8JP0``
+:deviceId: pre
+:decrypt password: ``E#U$MY$O2B=``
+:encrypt password: ``%526CBL$ZU3``
+
+Windows Mobile
+^^^^^^^^^^^^^^
+
+:Username: winmo
+:Password: ``ED227E10a628EB0E8Pm825Dw7114AC39``
+:deviceId: VERIZON_MOTOQ9C
+:decrypt password: ``7D671jt0C5E5d251``
+:Encrypt password: ``v93C8C2s12E0EBD``
+
+internal-tuner.pandora.com
+--------------------------
+
+Desktop (AIR) Client
+^^^^^^^^^^^^^^^^^^^^
+
+:Username: pandora one
+:Password: ``TVCKIBGS9AO9TSYLNNFUML0743LH82D``
+:deviceId: D01
+:Decrypt password: ``U#IO$RZPAB%VX2``
+:Encrypt password: ``2%3WCL*JU$MP]4``
+
+.. note::
+
+ Requires a Pandora One account. Fails at station.getPlaylist without one.
+
+Vista Widget
+^^^^^^^^^^^^
+
+:Username: windowsgadget
+:Password: ``EVCCIBGS9AOJTSYMNNFUML07VLH8JYP0``
+:deviceId: WG01
+:Decrypt password: ``E#IO$MYZOAB%FVR2``
+:Encrypt password: ``%22CML*ZU$8YXP[1``
+
diff --git a/json/play.rst b/json/play.rst
new file mode 100644
index 0000000..4766f2f
--- /dev/null
+++ b/json/play.rst
@@ -0,0 +1,209 @@
+.. _play:
+
+Play
+====
+
+.. _station-getPlaylist:
+
+Retrieve playlist
+-----------------
+
+:Method: station.getPlaylist
+
+This method *must* be sent over a TLS-encrypted connection.
+
+.. csv-table::
+ :header: Name ,Type ,Description
+
+ stationToken ,string ,station token from :ref:`user-getStationList`
+ additionalAudioUrl,string,Comma separated list of additional audio formats to return. (optional)
+ stationIsStarting,boolean,(optional)
+ includeTrackLength,boolean,(optional)
+ includeAudioToken,boolean,(optional)
+ xplatformAdCapable,boolean,(optional)
+ includeAudioReceiptUrl,boolean,(optional)
+ includeBackstageAdUrl,boolean,(optional)
+ includeSharingAdUrl,boolean,(optional)
+ includeSocialAdUrl,boolean,(optional)
+ includeCompetitiveSepIndicator,boolean,(optional)
+ includeCompletePlaylist,boolean,(optional)
+ includeTrackOptions,boolean,(optional)
+ audioAdPodCapable,boolean,(optional)
+
+Valid values for additionalAudioUrl are:
+
+- HTTP_40_AAC_MONO
+- HTTP_64_AAC
+- HTTP_32_AACPLUS
+- HTTP_64_AACPLUS
+- HTTP_24_AACPLUS_ADTS
+- HTTP_32_AACPLUS_ADTS
+- HTTP_64_AACPLUS_ADTS
+- HTTP_128_MP3
+- HTTP_32_WMA
+
+Usually a playlist contains four tracks.
+
+.. code:: json
+
+ {
+ "userAuthToken": "XXX",
+ "additionalAudioUrl": "HTTP_32_AACPLUS_ADTS,HTTP_64_AACPLUS_ADTS",
+ "syncTime": 1335841463,
+ "stationToken": "121193154444133035"
+ }
+
+.. csv-table::
+ :header: Name ,Type ,Description
+
+ items.additionalAudioUrl ,array/string ,List of additional audio urls in the requested order or single string if only one format was requested
+ items.songRating ,int , "1 if song was given a thumbs up, 0 if song was not rated yet"
+ items.audioUrlMap ,object ,Song audio format and bitrates returned differ based on what partner credentials are used.
+
+.. code:: json
+
+ {
+ "stat": "ok",
+ "result": {
+ "items": [{
+ "trackToken": "40b892bc5376e695c2e5c2b347227b85af2761b6aa417f736d9a79319b8f4cb97c9695a5f9a9a32aa2abaed43571235c",
+ "artistName": "Cannabich, Christian",
+ "albumName": "London Mozart Players, Christian Cannabich: Symphonies",
+ "amazonAlbumUrl": "http://www.amazon.com/dp/B000GW8ATU/?tag=wwwpandoracom-20",
+ "songExplorerUrl": "http://www.pandora.com/xml/music/song/london-mozart-players/christian-cannabich-symphonies/2-andantino?explicit=false",
+ "albumArtUrl": "http://cont-sv5-2.pandora.com/images/public/amz/5/2/9/7/095115137925_500W_488H.jpg",
+ "artistDetailUrl": "http://www.pandora.com/christian-cannabich?...",
+ "audioUrlMap": {
+ "highQuality": {
+ "bitrate": "64",
+ "encoding": "aacplus",
+ "audioUrl": "http://audio-sjl-t1-2.pandora.com/access/166132182435087962.mp4?...",
+ "protocol": "http"
+ },
+ "mediumQuality": {
+ "bitrate": "64",
+ "encoding": "aacplus",
+ "audioUrl": "http://t1-2.cdn.pandora.com/access/4127124196771074419.mp4?...",
+ "protocol": "http"
+ },
+ "lowQuality": {
+ "bitrate": "32",
+ "encoding": "aacplus",
+ "audioUrl": "http://audio-sv5-t1-1.pandora.com/access/3464788359714661029.mp4?...",
+ "protocol": "http"
+ }
+ },
+ "itunesSongUrl": "http://click.linksynergy.com/fs-bin/stat?...",
+ "additionalAudioUrl": [
+ "http://t1-2.cdn.pandora.com/access/6705986462049243054.mp4?...",
+ "http://audio-sjl-t1-1.pandora.com/access/2473529637452270302.mp4?..."
+ ],
+ "amazonAlbumAsin": "B000GW8ATU",
+ "amazonAlbumDigitalAsin": "B003H37NN4",
+ "artistExplorerUrl": "http://www.pandora.com/xml/music/composer/christian-cannabich?explicit=false",
+ "songName": "Symphony In G Major",
+ "albumDetailUrl": "http://www.pandora.com/london-mozart-players/christian-cannabich-symphonies?...",
+ "songDetailUrl": "http://www.pandora.com/london-mozart-players/christian-cannabich-symphonies/2-andantino?...",
+ "stationId": "121193154444133035",
+ "songRating": 0,
+ "trackGain": "10.09",
+ "albumExplorerUrl": "http://www.pandora.com/xml/music/album/london-mozart-players/christian-cannabich-symphonies?explicit=false",
+ "allowFeedback": true,
+ "amazonSongDigitalAsin": "B003H39AGW",
+ "nowPlayingStationAdUrl": "http://ad.doubleclick.net/pfadx/pand.android/prod.nowplaying..."
+ }, {
+ "adToken": "121193154444133035-none"
+ },
+ ]
+ }
+ }
+
+.. _station-addFeedback:
+
+Rate track
+----------
+
+:Method: station.addFeedback
+
+Songs can be “loved” or “banned”. Both influence the music played on the
+station. Banned songs are never played again on this particular station.
+
+.. csv-table::
+ :header: Name,Type,Description
+
+ stationToken,string,
+ trackToken,string,
+ isPositive,boolean,
+
+
+.. _user-sleepSong:
+
+Temporarily ban track
+---------------------
+
+:Method: user.sleepSong
+
+A song can be banned *from all stations* temporarily (one month).
+
+.. csv-table::
+ :header: Name ,Type ,Description
+
+ trackToken ,string ,See :ref:`station-getPlaylist`
+
+.. code:: json
+
+ {
+ "trackToken": "d6aa37c60833f12150c4e2ba172c46f24590ebc49df948b6fb7117314c41c8e7d4faee3568884468d9509db2ab998dafdbc4093baf8c38ef",
+ "userAuthToken": "XXX",
+ "syncTime": 1336386838
+ }
+
+Nothing is returned in the response.
+
+.. _track-explainTrack:
+
+Explain track choice
+--------------------
+
+:Method: track.explainTrack
+
+Get (incomplete) list of attributes assigned to song by Music Genome Project.
+
+.. csv-table::
+ :header: Name ,Type ,Description
+
+ trackToken ,string ,See :ref:`station-getPlaylist`
+
+.. code:: json
+
+ {
+ "trackToken": "94f36e09e341780c2ee7ebbb3581a55c4f2066dbaa60f2ee253ede5bc407fbd3c4f6db7ed00f92312437e020e0bf0e05d2924742c2ccece2",
+ "userAuthToken": "XXX",
+ "syncTime": 1336675993
+ }
+
+The request returns a list of attributes. Note that the last item is not an
+actual attribute.
+
+.. csv-table::
+ :header: Name ,Type ,Description
+
+ explanations ,array ,
+
+.. code:: json
+
+ {
+ "stat": "ok",
+ "result": {
+ "explanations": [{
+ "focusTraitName": "trance roots",
+ "focusTraitId": "F7524"
+ },
+ {
+ "focusTraitName": "many other similarities identified in the Music Genome Project",
+ "focusTraitId": "F4797"
+ }]
+ }
+ }
+
+
diff --git a/json/stations.rst b/json/stations.rst
new file mode 100644
index 0000000..b8e7821
--- /dev/null
+++ b/json/stations.rst
@@ -0,0 +1,289 @@
+.. _stations:
+
+Stations
+========
+
+A *station* is a collection of one or more user-supplied *seeds*. Artists or
+tracks can be used as seed. Based on the seeds Pandora decides which music to
+play.
+
+.. _user-getStationList:
+
+Retrieve station list
+---------------------
+
+:Method: user.getStationList
+
+.. csv-table::
+ :header: Name ,Type ,Description
+
+ includeStationArtUrl ,boolean ,Includes "artUrl" field in result (optional)
+ stationArtSize,string,“W130H130”
+ includeAdAttributes,boolean,(optional)
+ includeStationSeeds,boolean,(optional)
+ includeShuffleInsteadOfQuickMix,boolean,(optional)
+ includeRecommendations,boolean,(optional)
+ includeExplanations,boolean,(optional)
+
+.. code:: json
+
+ {
+ "userAuthToken": "XXX",
+ "syncTime": XXX
+ }
+
+Currently stationId and stationToken are the same.
+
+QuickMix stations additionally include a list of station ids
+(quickMixStationIds) that are currently selected for the mix.
+
+.. csv-table::
+ :header: Name ,Type ,Description
+
+ stations.stationId,string,
+ stations.stationName,string,
+ checksum,string,
+
+.. code:: json
+
+ {
+ "stat":"ok",
+ "result":{
+ "stations":[
+ {
+ "suppressVideoAds":true,
+ "isQuickMix":true,
+ "stationId":"3914377363925265",
+ "stationDetailUrl":"https://www.pandora.com/login?target=%2Fstations%2Fa61985110ea3d6c6c8d8a9c038588b26425ba2910f7abf8b",
+ "isShared":false,
+ "dateCreated":{
+ "date":8,
+ "day":4,
+ "hours":22,
+ "minutes":44,
+ "month":10,
+ "nanos":241000000,
+ "seconds":46,
+ "time":1194590686241,
+ "timezoneOffset":480,
+ "year":107
+ },
+ "stationToken":"3914377363925265",
+ "stationName":"QuickMix",
+ "stationSharingUrl":"https://www.pandora.com/login?target=%2Fshare%2Fstation%2Fa61985110ea3d6c6c8d8a9c038588b26425ba2910f7abf8b",
+ "requiresCleanAds":true,
+ "allowRename":false,
+ "allowAddMusic":false,
+ "quickMixStationIds":[
+ "339646069607180561",
+ "339644480469281041"
+ ],
+ "allowDelete":false
+ }
+ ],
+ "checksum":"99776ddd31ad798895578593e78e3691"
+ }
+ }
+
+.. _user-getStationListChecksum:
+
+Check station list for modifications
+------------------------------------
+
+:Method: user.getStationListChecksum
+
+To check if the station list was modified by another client the checksum can be
+fetched. No parameters are required for this request.
+
+The response contains the new checksum.
+
+.. csv-table::
+ :header: Name,Type,Description
+
+ checksum,string,
+
+.. code:: json
+
+ {
+ "stat":"ok",
+ "result":{
+ "checksum":"99776ddd31ad798895578593e78e3691"
+ }
+ }
+
+Add new station
+---------------
+
+New stations can be created by searching for an artist/song or using a track
+from a playlist.
+
+.. _music-search:
+
+Search
+^^^^^^
+
+:Method: music.search
+
+This is a free text search that matches artist and track names.
+
+.. csv-table::
+ :header: Name ,Type ,Description
+
+ searchText ,string ,Artist name or track title
+
+.. code:: json
+
+ {
+ "searchText": "encore",
+ "userAuthToken": "XXX",
+ "syncTime": 1335869287
+ }
+
+Matching songs and artists are returned in two separate list.
+
+.. csv-table::
+ :header: Name ,Type ,Description
+
+ songs.musicToken and artists.musicToken ,string ,
+
+.. code:: json
+
+ {
+ "stat": "ok",
+ "result": {
+ "nearMatchesAvailable": true,
+ "explanation": "",
+ "songs": [{
+ "artistName": "Jason DeRulo",
+ "musicToken": "S1508963",
+ "songName": "Encore",
+ "score": 100
+ }],
+ "artists": [{
+ "artistName": "Encore",
+ "musicToken": "R175304",
+ "likelyMatch": false,
+ "score": 100
+ }]
+ }
+ }
+
+.. _station-createStation:
+
+Create
+^^^^^^
+
+:Method: station.createStation
+
+Stations can either be created with a musicToken obtained by
+:ref:`music-search` or trackToken from playlists (:ref:`station-getPlaylist`).
+The latter needs a musicType to specify whether the track itself or its artist
+should be used as seed.
+
+.. csv-table::
+ :header: Name,Type,Description
+
+ trackToken,string,See :ref:`station-getPlaylist`
+ musicType,string,“song” or “artist”
+ musicToken,string,See :ref:`music-search`
+
+.. _station-addMusic:
+
+Add seed
+--------
+
+:Method: station.addMusic
+
+:ref:`music-search` results can be used to add new seeds to an existing
+station.
+
+.. csv-table::
+ :header: Name,Type,Description
+
+ stationToken,string,"Existing station, see :ref:`user-getStationList`"
+ musicToken,string,"See :ref:`music-search`"
+
+.. _station-renameStation:
+
+Rename station
+--------------
+
+:Method: station.renameStation
+
+.. csv-table::
+ :header: Name,Type,Description
+
+ stationToken,string,"Existing station, see :ref:`user-getStationList`"
+ stationName,string,New station name
+
+.. _station-deleteStation:
+
+Delete station
+--------------
+
+:Method: station.deleteStation
+
+.. csv-table::
+ :header: Name,Type,Description
+
+ stationToken,string,"Existing station, see :ref:`user-getStationList`"
+
+.. _station-getGenreStations:
+
+Predefined stations
+-------------------
+
+:Method: station.getGenreStations
+
+Pandora provides a list of predefined stations (“genre stations”). The request
+has no parameters.
+
+Each station belongs to one category, usually a genre name. stationToken can be
+used as musicToken to create a new station with :ref:`station-createStation`.
+
+.. csv-table::
+ :header: Name ,Type ,Description
+
+ categories ,array ,List of categories
+ categories.stations ,array ,List of stations in category
+ categories.stations.stationToken,string,"Actually a musicToken, see :ref:`station-createStation`"
+ catogories.categoryName,string,Category name
+
+.. code:: json
+
+ {
+ "stat": "ok",
+ "result": {
+ "categories": [{
+ "stations": [{
+ "stationToken": "G165",
+ "stationName": "90s Alternative ",
+ "stationId": "G165"
+ }],
+ "categoryName": "Alternative"
+ }]
+ }
+ }
+
+.. _user-setQuickMix:
+
+Modify QuickMix
+---------------
+
+:Method: user.setQuickMix
+
+.. csv-table::
+ :header: Name ,Type ,Description
+
+ quickMixStationIds ,array ,List of station id’s (strings)
+
+.. code:: json
+
+ {
+ "quickMixStationIds": ["404958383414849005", "403387202773593581"],
+ "userAuthToken": "XXX",
+ "syncTime": 1338211186
+ }
+
+The response contains no data.
+