summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--LICENSE14
-rw-r--r--Makefile153
-rw-r--r--conf.py242
-rw-r--r--index.rst24
-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
-rw-r--r--make.bat190
14 files changed, 1705 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e81d4a3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+_build
+*.sw?
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..ee7d6a5
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,14 @@
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ Version 2, December 2004
+
+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
+
+ Everyone is permitted to copy and distribute verbatim or modified
+ copies of this license document, and changing it is allowed as long
+ as the name is changed.
+
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..16e1711
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,153 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ -rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PandoraAPIdocumentation.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PandoraAPIdocumentation.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/PandoraAPIdocumentation"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/PandoraAPIdocumentation"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/conf.py b/conf.py
new file mode 100644
index 0000000..34dea7e
--- /dev/null
+++ b/conf.py
@@ -0,0 +1,242 @@
+# -*- coding: utf-8 -*-
+#
+# Pandora API documentation documentation build configuration file, created by
+# sphinx-quickstart on Mon Jun 30 21:53:24 2014.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = []
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Unofficial Pandora API'
+copyright = u''
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = ''
+# The full version, including alpha/beta/rc tags.
+release = ''
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'PandoraAPIdocumentationdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+ ('index', 'PandoraAPIdocumentation.tex', u'Pandora API documentation Documentation',
+ u'People', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'pandoraapidocumentation', u'Pandora API documentation Documentation',
+ [u'People'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output ------------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ ('index', 'PandoraAPIdocumentation', u'Pandora API documentation Documentation',
+ u'People', 'PandoraAPIdocumentation', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
diff --git a/index.rst b/index.rst
new file mode 100644
index 0000000..c7dcc78
--- /dev/null
+++ b/index.rst
@@ -0,0 +1,24 @@
+Unofficial Pandora API documentation
+====================================
+
+This documentation project replaces the Wiki_ hosted by wikia_, which got taken
+down by Pandora_ (`read more`_). It aims to provide language-independent
+documentation of Pandora’s `proprietary API`_.
+
+.. _Wiki: http://pan-do-ra-api.wikia.com/
+.. _wikia: http://www.wikia.com/
+.. _Pandora: http://www.pandora.com/
+.. _Read more: http://6xq.net/blog/2014/dmca/
+.. _proprietary API: http://developer.pandora.com/
+
+The source code of this documentation is available at `github`_ or `here`_.
+Suggestions and patches are welcome.
+
+.. _github: http://github.com/promyloph/pandora-apidoc/
+.. _here: http://6xq.net/git/pandora-apidoc.git
+
+.. toctree::
+ :maxdepth: 2
+
+ json/index
+
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.
+
diff --git a/make.bat b/make.bat
new file mode 100644
index 0000000..95f36f4
--- /dev/null
+++ b/make.bat
@@ -0,0 +1,190 @@
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+set I18NSPHINXOPTS=%SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+ set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+ set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+ :help
+ echo.Please use `make ^<target^>` where ^<target^> is one of
+ echo. html to make standalone HTML files
+ echo. dirhtml to make HTML files named index.html in directories
+ echo. singlehtml to make a single large HTML file
+ echo. pickle to make pickle files
+ echo. json to make JSON files
+ echo. htmlhelp to make HTML files and a HTML help project
+ echo. qthelp to make HTML files and a qthelp project
+ echo. devhelp to make HTML files and a Devhelp project
+ echo. epub to make an epub
+ echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+ echo. text to make text files
+ echo. man to make manual pages
+ echo. texinfo to make Texinfo files
+ echo. gettext to make PO message catalogs
+ echo. changes to make an overview over all changed/added/deprecated items
+ echo. linkcheck to check all external links for integrity
+ echo. doctest to run all doctests embedded in the documentation if enabled
+ goto end
+)
+
+if "%1" == "clean" (
+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+ del /q /s %BUILDDIR%\*
+ goto end
+)
+
+if "%1" == "html" (
+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+ goto end
+)
+
+if "%1" == "dirhtml" (
+ %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+ goto end
+)
+
+if "%1" == "singlehtml" (
+ %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+ goto end
+)
+
+if "%1" == "pickle" (
+ %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the pickle files.
+ goto end
+)
+
+if "%1" == "json" (
+ %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the JSON files.
+ goto end
+)
+
+if "%1" == "htmlhelp" (
+ %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+ goto end
+)
+
+if "%1" == "qthelp" (
+ %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\PandoraAPIdocumentation.qhcp
+ echo.To view the help file:
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\PandoraAPIdocumentation.ghc
+ goto end
+)
+
+if "%1" == "devhelp" (
+ %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished.
+ goto end
+)
+
+if "%1" == "epub" (
+ %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The epub file is in %BUILDDIR%/epub.
+ goto end
+)
+
+if "%1" == "latex" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "text" (
+ %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The text files are in %BUILDDIR%/text.
+ goto end
+)
+
+if "%1" == "man" (
+ %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The manual pages are in %BUILDDIR%/man.
+ goto end
+)
+
+if "%1" == "texinfo" (
+ %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
+ goto end
+)
+
+if "%1" == "gettext" (
+ %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
+ goto end
+)
+
+if "%1" == "changes" (
+ %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.The overview file is in %BUILDDIR%/changes.
+ goto end
+)
+
+if "%1" == "linkcheck" (
+ %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+ goto end
+)
+
+if "%1" == "doctest" (
+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+ goto end
+)
+
+:end