gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-anastasis] branch master updated: Added API for mast


From: gnunet
Subject: [GNUnet-SVN] [taler-anastasis] branch master updated: Added API for masterkey and backup recovery. Signed commit. In progress...
Date: Mon, 29 Jul 2019 12:54:30 +0200

This is an automated email from the git hooks/post-receive script.

dennis-neufeld pushed a commit to branch master
in repository anastasis.

The following commit(s) were added to refs/heads/master by this push:
     new 3be5b7c  Added API for masterkey and backup recovery. Signed commit. 
In progress...
3be5b7c is described below

commit 3be5b7c34b69c6a120f822f0b16ad4ff1b0134f6
Author: Dennis Neufeld <address@hidden>
AuthorDate: Mon Jul 29 12:54:25 2019 +0200

    Added API for masterkey and backup recovery. Signed commit. In progress...
---
 src/api/.dir-locals.el                         |   16 +
 src/api/.gitignore                             |    2 +
 src/api/AUTHORS                                |    5 +
 src/api/COPYING                                |  674 +++++++++++
 src/api/COPYING.AGPL                           |  661 ++++++++++
 src/api/COPYING.GPL                            |  674 +++++++++++
 src/api/COPYING.LGPL                           |  510 ++++++++
 src/api/Makefile                               |  179 +++
 src/api/_static/.gitignore                     |    0
 src/api/api-anastasis.rst                      |  334 +++++
 src/api/api-auditor.rst                        |  232 ++++
 src/api/api-bank.rst                           |  392 ++++++
 src/api/api-common.rst                         |  812 +++++++++++++
 src/api/api-error.rst                          | 1204 ++++++++++++++++++
 src/api/api-exchange.rst                       | 1546 ++++++++++++++++++++++++
 src/api/api-merchant.rst                       | 1200 ++++++++++++++++++
 src/api/api-sync.rst                           |  407 +++++++
 src/api/cf/captcha-payment.txt                 |  116 ++
 src/api/conf.py                                |  285 +++++
 src/api/diagram.dot                            |   21 +
 src/api/exts/httpdomain/__init__.py            |   14 +
 src/api/exts/httpdomain/autohttp/__init__.py   |   11 +
 src/api/exts/httpdomain/autohttp/bottle.py     |  114 ++
 src/api/exts/httpdomain/autohttp/common.py     |   36 +
 src/api/exts/httpdomain/autohttp/flask.py      |   48 +
 src/api/exts/httpdomain/autohttp/flask_base.py |  215 ++++
 src/api/exts/httpdomain/autohttp/flaskqref.py  |   80 ++
 src/api/exts/httpdomain/autohttp/tornado.py    |  128 ++
 src/api/exts/httpdomain/httpdomain.py          |  771 ++++++++++++
 src/api/exts/tslex.py                          |   88 ++
 src/api/exts/tsref.py                          |  233 ++++
 src/api/global-licensing.rst                   |  215 ++++
 src/api/index.rst                              |   71 ++
 src/api/wireformats.rst                        |   70 ++
 34 files changed, 11364 insertions(+)

diff --git a/src/api/.dir-locals.el b/src/api/.dir-locals.el
new file mode 100644
index 0000000..6878638
--- /dev/null
+++ b/src/api/.dir-locals.el
@@ -0,0 +1,16 @@
+;; Per-directory local variables for GNU Emacs 23 and later.
+
+((nil
+  . ((fill-column . 78)
+     (tab-width   .  4)
+     (indent-tabs-mode . nil)
+     (show-trailing-whitespace . t)
+     (c-basic-offset . 2)
+     (ispell-check-comments . exclusive)
+     (ispell-local-dictionary . "american")
+     (safe-local-variable-values
+         '((c-default-style . "gnu")
+           (sentence-end-double-space . f)
+        (eval add-hook 'prog-mode-hook #'flyspell-prog-mode)
+        (flyspell-issue-message-flag . f) ; avoid messages for every word
+        )))))
diff --git a/src/api/.gitignore b/src/api/.gitignore
new file mode 100644
index 0000000..9dee836
--- /dev/null
+++ b/src/api/.gitignore
@@ -0,0 +1,2 @@
+_build
+*.pyc
diff --git a/src/api/AUTHORS b/src/api/AUTHORS
new file mode 100644
index 0000000..aed0f6d
--- /dev/null
+++ b/src/api/AUTHORS
@@ -0,0 +1,5 @@
+Marcello Stanisci
+Sree Harsha Totakura <address@hidden>
+Florian Dold
+Christian Grothoff
+Benedikt Muller
diff --git a/src/api/COPYING b/src/api/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/src/api/COPYING
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/src/api/COPYING.AGPL b/src/api/COPYING.AGPL
new file mode 100644
index 0000000..dba13ed
--- /dev/null
+++ b/src/api/COPYING.AGPL
@@ -0,0 +1,661 @@
+                    GNU AFFERO GENERAL PUBLIC LICENSE
+                       Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+  A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate.  Many developers of free software are heartened and
+encouraged by the resulting cooperation.  However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+  The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community.  It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server.  Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+  An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals.  This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU Affero General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Remote Network Interaction; Use with the GNU General Public License.
+
+  Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software.  This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time.  Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source.  For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code.  There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+<http://www.gnu.org/licenses/>.
diff --git a/src/api/COPYING.GPL b/src/api/COPYING.GPL
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/src/api/COPYING.GPL
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/src/api/COPYING.LGPL b/src/api/COPYING.LGPL
new file mode 100644
index 0000000..9b3e553
--- /dev/null
+++ b/src/api/COPYING.LGPL
@@ -0,0 +1,510 @@
+Some of this code is DUAL-LICENSED.  If you use MHD without HTTPS/SSL
+support, you are free to choose between the LGPL and the eCos License
+(http://ecos.sourceware.org/license-overview.html).  If you compile
+MHD with HTTPS support, you must obey the terms of the GNU LGPL.
+
+
+                 GNU LESSER GENERAL PUBLIC LICENSE
+                      Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                 GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                           NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  
USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/src/api/Makefile b/src/api/Makefile
new file mode 100644
index 0000000..f09f2a0
--- /dev/null
+++ b/src/api/Makefile
@@ -0,0 +1,179 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# User-friendly check for sphinx-build
+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
+$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx 
installed, then set the SPHINXBUILD environment variable to point to the full 
path of the '$(SPHINXBUILD)' executable. Alternatively you can add the 
directory with the executable to your PATH. If you don't have Sphinx installed, 
grab it from http://sphinx-doc.org/)
+endif
+
+# 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 "  latexpdfja to make LaTeX files and run them through 
platex/dvipdfmx"
+       @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 "  xml        to make Docutils-native XML files"
+       @echo "  pseudoxml  to make pseudoxml-XML files for display purposes"
+       @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)/*
+
+# The html-linked builder does not support caching, so we
+# remove all cached state first.
+html:
+       $(SPHINXBUILD) -b html-linked $(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/neuro.qhcp"
+       @echo "To view the help file:"
+       @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/neuro.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/neuro"
+       @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/neuro"
+       @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."
+
+latexpdfja:
+       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+       @echo "Running LaTeX files through platex and dvipdfmx..."
+       $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
+       @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."
+
+xml:
+       $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
+       @echo
+       @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
+
+pseudoxml:
+       $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
+       @echo
+       @echo "Build finished. The pseudo-XML files are in 
$(BUILDDIR)/pseudoxml."
diff --git a/src/api/_static/.gitignore b/src/api/_static/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/src/api/api-anastasis.rst b/src/api/api-anastasis.rst
new file mode 100644
index 0000000..c47c268
--- /dev/null
+++ b/src/api/api-anastasis.rst
@@ -0,0 +1,334 @@
+..
+  This file is part of GNU TALER.
+  Copyright (C) 2014-2018 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU General Public License as published by the Free Software
+  Foundation; either version 2.1, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
details.
+
+  You should have received a copy of the GNU Lesser General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+
+  @author Christian Grothoff
+
+==============================
+The Anastasis RESTful JSON API
+==============================
+
+The API specified here follows the :ref:`general conventions <http-common>`
+for all details not specified in the individual requests.
+
+.. _registration:
+
+---------------------------
+Register to Escrow Provider
+---------------------------
+
+This API is used by Anastasis clients to obtain global information about
+the escrow provider, such as online signing keys and the fee
+structure.  This is typically the first call any Anastasis client makes, as it
+returns information required to process all of the other interactions with the
+escrow provider.  The returned information is secured by (1) signature(s) from 
the escrow provider,
+especially the long-term offline signing key of the escrow provider, which 
clients should
+cache; (2) possibly by using HTTPS.
+
+
+.. http:get:: /escrow/registration
+
+  Get the providers's current online signing key.
+
+  **Request:** The request body must be a `RegistrationRequest`_ object.
+
+  :query last_issue_date: optional argument specifying the maximum value of 
any of the "stamp_start" members of the denomination keys of a "/register" 
response that is already known to the client. Allows the exchange to only 
return keys that have changed since that timestamp.  The given value must be an 
unsigned 64-bit integer representing seconds after 1970.  If the timestamp does 
not exactly match the "stamp_start" of one of the denomination keys, all keys 
are returned.
+
+  **Response:**
+
+  :status 200 OK:
+    The escrow provider responds with a `EscrowInitResponse`_ object. This 
request should
+    virtually always be successful.
+
+  **Details:**
+
+  .. _EscrowInitResponse:
+  .. code-block:: tsref
+
+    interface EscrowInitResponse {
+      // EdDSA master public key of the escrow provider
+      master_public_key: EddsaPublicKey;
+
+      // Relative duration until inactive reserves are closed; not signed, 
expressed as
+      // a string in relative time in microseconds, i.e. "/Delay(1000)/" for 1 
second.
+      reserve_closing_delay: RelativeTime;
+
+      // The escrow provider's signing key.
+      signkey: SignKey;
+  
+      // The  hashed and salted identification (e.g. AHV number) of the client.
+      clientId_J: HashedClientId;
+
+      // Some metadata of the client/customer
+      customer: Customer;
+
+      // The type of contract (free or paid abonnement etc.)
+      contractType: String;
+    }
+
+  .. note::
+
+      Hash Algorithm for clientId_J must be different from the one used for 
the clientId_I used for the key provider!
+
+.. _policy:
+
+---------------------------------
+Send policy to escrow provider
+---------------------------------
+
+This API is used by Anastasis clients to send a defined policy for masterkey 
recovery to the escrow provider.
+
+
+.. http:post:: /escrow/policy
+
+  Send a defined policy for masterkey recovery.
+
+  **Request:** The request body must be a `SignedPolicy`_ object.
+
+  **Response:**
+
+  :status 200 OK:
+    The key provider responds with a `PolicyStatus`_ object. This request 
should
+    virtually always be successful.
+
+  **Details:**
+
+  .. _PolicyStatus:
+  .. code-block:: tsref
+       
+    interface PolicyStatus {
+     
+    }
+
+---------------------------------
+Get policies from escrow provider
+---------------------------------
+
+This API is used by Anastasis clients to get the policies to recovery the 
masterkey.
+
+
+.. http:get:: /escrow/policy
+
+  Get the policies for masterkey recovery.
+
+  **Request:** The request body must be a `PolicyRequest`_ object.
+
+  **Response:**
+
+  :status 200 OK:
+    The key provider responds with a `Policies`_ object. This request should
+    virtually always be successful.
+
+  **Details:**
+
+  .. _Policies:
+  .. code-block:: tsref
+       
+    interface Policies {
+     
+    }
+
+.. _masterkey:
+
+---------------------------------
+Send masterkey to escrow provider
+---------------------------------
+
+This API is used by Anastasis clients to send the encrypted masterkey to the 
escrow provider.
+
+
+.. http:post:: /escrow/masterkey
+
+  Send the masterkey to the escrow provider.
+
+  **Request:** The request body must be a `MasterkeyBackup`_ object.
+
+  **Response:**
+
+  :status 200 OK:
+    The key provider responds with a `MasterkeyStatus`_ object. This request 
should
+    virtually always be successful.
+
+  **Details:**
+
+  .. _MasterkeyStatus:
+  .. code-block:: tsref
+       
+    interface MasterkeyStatus {
+     
+    }
+
+---------------------------------
+Obtain masterkey from escrow provider
+---------------------------------
+
+This API is used by Anastasis clients to obtain the encrypted masterkey from 
the escrow provider.
+
+
+.. http:get:: /escrow/masterkey
+
+  Obtain the masterkey from the escrow provider.
+
+  **Request:** The request body must be a `MasterkeyRequest`_ object.
+
+  **Response:**
+
+  :status 200 OK:
+    The key provider responds with a `MasterkeyResponse`_ object. This request 
should
+    virtually always be successful.
+
+  **Details:**
+
+  .. _MasterkeyResponse:
+  .. code-block:: tsref
+       
+    interface MasterkeyResponse {
+      // Encrypted masterkey
+      masterkey: Masterkey;
+    }
+
+.. _backup:
+
+---------------------------------
+Send backup file to escrow provider
+---------------------------------
+
+This API is used by Anastasis clients to send an encrypted backup (wallet 
etc.) to the escrow provider.
+
+.. http:post:: /escrow/backup
+
+  Send the backup file to the escrow provider.
+
+  **Request:** The request body must be a `FileBackup`_ object.
+
+  **Response:**
+
+  :status 200 OK:
+    The key provider responds with a `BackupStatus`_ object. This request 
should
+    virtually always be successful.
+
+  **Details:**
+
+  .. _BackupStatus:
+  .. code-block:: tsref
+       
+    interface BackupStatus {
+     
+    }
+
+---------------------------------
+Obtain backup file from escrow provider
+---------------------------------
+
+This API is used by Anastasis clients to obtain encrypted backup file (wallet 
etc.) from the escrow provider.
+
+
+.. http:get:: /escrow/backup
+
+  Obtain the backup file from the escrow provider.
+
+  **Request:** The request body must be a `FileBackupRequest`_ object.
+
+  **Response:**
+
+  :status 200 OK:
+    The key provider responds with a `FileBackupResponse`_ object. This 
request should
+    virtually always be successful.
+
+  **Details:**
+
+  .. _FileBackupResponse:
+  .. code-block:: tsref
+       
+    interface FileBackupResponse {
+      // Encrypted and signed backup file
+      backup: FileBackup;
+    }
+
+
+.. _depositkey:
+
+---------------------------------
+Deposit a key with a Key Provider
+---------------------------------
+
+This API is used by Anastasis clients to deposit a key with a key provider in 
accordance with a pre-defined policy.
+
+
+.. http:post:: /keydepo/depositkey
+
+  Get the key providers's current online signing key and a specific index for 
the key deposited.
+
+  **Request:** The request body must be a `KeyDepositRequest`_ object.
+
+  **Response:**
+
+  :status 200 OK:
+    The key provider responds with a `KeyDepositResponse`_ object. This 
request should
+    virtually always be successful.
+
+  **Details:**
+
+  .. _KeyDepositResponse:
+  .. code-block:: tsref
+       
+    interface KeyDepositResponse {
+      // EdDSA master public key of the key provider
+      master_public_key: EddsaPublicKey;
+
+      // Relative duration until inactive reserves are closed; not signed, 
expressed as
+      // a string in relative time in microseconds, i.e. "/Delay(1000)/" for 1 
second.
+      reserve_closing_delay: RelativeTime;
+
+      // The key provider's signing key.
+      signkey: SignKey;
+
+      // The index of the key deposited
+      indexkey: Integer;       
+    }
+
+.. _obtainkey:
+
+---------------------------------
+Obtain a key from a Key Provider
+---------------------------------
+
+This API is used by Anastasis clients to deposit a key with a key provider in 
accordance with a pre-defined policy.
+
+
+.. http:get:: /keydepo/obtainkey
+
+  Get the key providers's current online signing key and a specific index for 
the key deposited.
+
+  **Request:** The request body must be a `KeyObtainRequest`_ object.
+
+  **Response:**
+
+  :status 200 OK:
+    The key provider responds with a `KeyObtainResponse`_ object. This request 
should
+    virtually always be successful.
+
+  **Details:**
+
+  .. _KeyObtainResponse:
+  .. code-block:: tsref
+       
+    interface KeyObtainResponse {
+      // The index of the key obtained
+      index: Integer;
+
+      // The requested key
+      key: HashedKey;  
+    }
+
diff --git a/src/api/api-auditor.rst b/src/api/api-auditor.rst
new file mode 100644
index 0000000..957b1c0
--- /dev/null
+++ b/src/api/api-auditor.rst
@@ -0,0 +1,232 @@
+..
+  This file is part of GNU TALER.
+  Copyright (C) 2018 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU General Public License as published by the Free Software
+  Foundation; either version 2.1, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
details.
+
+  You should have received a copy of the GNU Lesser General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+
+  @author Christian Grothoff
+
+============================
+The Auditor RESTful JSON API
+============================
+
+The API specified here follows the :ref:`general conventions <http-common>`
+for all details not specified in the individual requests.
+The `glossary <https://docs.taler.net/glossary.html#glossary>`
+defines all specific terms used in this section.
+
+.. _auditor-version:
+
+-------------------------
+Obtaining Auditor Version
+-------------------------
+
+This API is used by merchants to obtain a list of all exchanges audited by
+this auditor.  This may be required for the merchant to perform the required
+know-your-customer (KYC) registration before issuing contracts.
+
+.. http:get:: /version
+
+  Get the protocol version and some meta data about the auditor.
+
+  **Response:**
+
+  :status 200 OK:
+    The auditor responds with a `AuditorVersion`_ object. This request should
+    virtually always be successful.
+
+  **Details:**
+
+  .. _AuditorVersion:
+  .. code-block:: tsref
+
+    interface AuditorVersion {
+      // libtool-style representation of the Taler protocol version, see
+      // 
https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
+      // The format is "current:revision:age".  Note that the auditor
+      // protocol is versioned independently of the exchange's protocol.
+      version: String;
+
+      // Return which currency this auditor is auditing for.
+      currency: String;
+
+      // EdDSA master public key of the auditor
+      auditor_public_key: EddsaPublicKey;
+    }
+
+  .. note::
+
+    This API is still experimental (and is not yet implemented at the
+    time of this writing).
+
+
+.. _exchange-list:
+
+-----------------------
+Obtaining Exchange List
+-----------------------
+
+This API is used by merchants to obtain a list of all exchanges audited by
+this auditor.  This may be required for the merchant to perform the required
+know-your-customer (KYC) registration before issuing contracts.
+
+.. http:get:: /exchanges
+
+  Get a list of all exchanges audited by the auditor.
+
+  **Response:**
+
+  :status 200 OK:
+    The auditor responds with a `ExchangeList`_ object. This request should
+    virtually always be successful.
+
+  **Details:**
+
+  .. _ExchangeList:
+  .. code-block:: tsref
+
+    interface ExchangeList {
+      // Exchanges audited by this auditor
+      exchanges: ExchangeEntry[];
+    }
+
+  .. _tsref-type-Denom:
+  .. code-block:: tsref
+
+    interface ExchangeEntry {
+
+      // Master public key of the exchange
+      master_pub: EddsaPublicKey;
+
+      // Base URL of the exchange
+      exchange_url: string;
+    }
+
+  .. note::
+
+    This API is still experimental (and is not yet implemented at the
+    time of this writing). A key open question is whether the auditor
+    should sign the information. We might also want to support more
+    delta downloads in the future.
+
+.. _deposit-confirmation:
+
+--------------------------------
+Submitting deposit confirmations
+--------------------------------
+
+Merchants should probabilistically submit some of the deposit
+confirmations they receive from the exchange to auditors to ensure
+that the exchange does not lie about recording deposit confirmations
+with the exchange. Participating in this scheme ensures that in case
+an exchange runs into financial trouble to pay its obligations, the
+merchants that did participate in detecting the bad behavior can be
+paid out first.
+
+.. http:put:: /deposit-confirmation
+
+   Submits a `DepositConfirmation`_ to the exchange. Should succeed
+   unless the signature provided is invalid or the exchange is not
+   audited by this auditor.
+
+  **Response:**
+
+  :status 200: The auditor responds with a `DepositAudited`_ object.
+               This request should virtually always be successful.
+
+  **Details:**
+
+  .. _DepositAudited:
+  .. _tsref-type-DepositAudited:
+  .. code-block:: tsref
+
+    interface DepositAudited {
+        // TODO: do we care for the auditor to sign this?
+    }
+
+  .. _DepositConfirmation:
+  .. _tsref-type-DepositConfirmation:
+  .. code-block:: tsref
+
+    interface DepositConfirmation {
+
+      // Hash over the contract for which this deposit is made.
+      h_contract_terms: HashCode;
+
+      // Hash over the wiring information of the merchant.
+      h_wire: HashCode;
+
+      // Time when the deposit confirmation confirmation was generated.
+      timestamp: Timestamp;
+
+      // How much time does the merchant have to issue a refund
+      // request?  Zero if refunds are not allowed.
+      refund_deadline : Timestamp;
+
+      // Amount to be deposited, excluding fee.  Calculated from the
+      // amount with fee and the fee from the deposit request.
+      amount_without_fee: Amount;
+
+      // The coin's public key.  This is the value that must have been
+      // signed (blindly) by the Exchange.  The deposit request is to be
+      // signed by the corresponding private key (using EdDSA).
+      coin_pub: CoinPublicKey;
+
+      // The Merchant's public key.  Allows the merchant to later refund
+      // the transaction or to inquire about the wire transfer identifier.
+      merchant_pub: EddsaPublicKey;
+
+      // Signature from the exchange of type
+      // TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT.
+      exchange_sig: EddsaSignature;
+
+      // Public signing key from the exchange matching @e exchange_sig.
+      exchange_pub: EddsaPublicKey;
+
+      // Master public key of the exchange corresponding to @e master_sig.
+      // Identifies the exchange this is about.
+      master_pub: EddsaPublicKey;
+
+      // When does the validity of the exchange_pub end?
+      ep_start: Timestamp;
+
+      // When will the exchange stop using the signing key?
+      ep_expire: Timestamp;
+
+      // When does the validity of the exchange_pub end?
+      ep_end: Timestamp;
+
+      // Exchange master signature over @e exchange_sig.
+      master_sig: EddsaSignature;
+    }
+
+  .. note::
+
+    This API is still experimental (and is not yet implemented at the
+    time of this writing). A key open question is whether the auditor
+    should sign the response information.
+
+
+----------
+Complaints
+----------
+
+This API is used by the wallet or merchants to submit proof of
+misbehavior of an exchange to the auditor.
+
+  .. note::
+
+     To be designed and implemented.
+
+  .. http:put:: /complain
+
+  Complain about missbehavior to the auditor.
diff --git a/src/api/api-bank.rst b/src/api/api-bank.rst
new file mode 100644
index 0000000..07de819
--- /dev/null
+++ b/src/api/api-bank.rst
@@ -0,0 +1,392 @@
+..
+  This file is part of GNU TALER.
+
+  Copyright (C) 2014, 2015, 2016, 2017 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU General Public License as published by the Free Software
+  Foundation; either version 2.1, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+
+  @author Marcello Stanisci
+  @author Christian Grothoff
+
+=========
+Bank API
+=========
+
+This API provides programmatic user registration at the bank.
+
+.. _bank-register:
+.. http:post:: /register
+
+**Request** The body of this request must have the format of a 
`BankRegistrationRequest`_.
+
+**Response**
+
+:status 200 OK: The new user has been correctly registered.
+:status 409 Conflict: the username requested by the client is not available 
anymore
+:status 406 Not Acceptable: unacceptable characters were given for the 
username. See 
https://docs.djangoproject.com/en/2.2/ref/contrib/auth/#django.contrib.auth.models.User.username
 for the accepted character set.
+
+**Details**
+
+.. _BankRegistrationRequest:
+.. code-block:: tsref
+
+  interface BankRegistrationRequest {
+  
+    // Username to use for registration; max length is 150 chars.
+    username: string;
+
+    // Password to associate with the username.  Any characters and
+    // any length are valid; next releases will enforce a minimum length
+    // and a safer characters choice.
+    password: string;
+  }
+
+
+This API provides programmatic withdrawal of cash via Taler to all the
+users registered at the bank.  It triggers a wire transfer from the client
+bank account to the exchange's.
+
+.. _bank-register:
+.. http:post:: /taler/withdraw
+
+**Request** The body of this request must have the format of a 
`BankTalerWithdrawRequest`_.
+
+**Response**
+
+:status 200 OK: The withdrawal was correctly initiated, therefore the exchange 
received the payment.  A `BankTalerWithdrawResponse`_ object is returned.
+:status 406 Not Acceptable: the user does not have sufficient credit to 
fulfill their request.
+:status 404 Not Found: The exchange wire details did not point to any valid 
bank account.
+
+**Details**
+
+.. _BankTalerWithdrawRequest:
+.. code-block:: tsref
+
+  interface BankTalerWithdrawRequest {
+
+    // Authentication method used
+    auth: BankAuth;
+  
+    // Amount to withdraw.
+    amount: Amount;
+
+    // Reserve public key.
+    reserve_pub: string;
+
+    // Exchange bank details specified in the 'payto'
+    // format.  NOTE: this field is optional, therefore
+    // the bank will initiate the withdrawal with the
+    // default exchange, if not given.
+    exchange_wire_details: string;
+  }
+
+.. _BankTalerWithdrawResponse:
+.. code-block:: tsref
+
+  interface BankTalerWithdrawResponse {
+
+    // Sender account details in 'payto' format.
+    sender_wire_details: string;
+
+    // Exchange base URL.  Optional: only returned
+    // if the user used the default exchange.
+    exchange_url: string;
+  }
+
+This API allows one user to send money to another user, within the same "test"
+bank.  The user calling it has to authenticate by including his credentials in 
the
+request.
+
+.. _bank-deposit:
+.. http:post:: /admin/add/incoming
+
+**Request:** The body of this request must have the format of a 
`BankDepositRequest`_.
+
+**Response:**
+
+:status 200 OK: The request has been correctly handled, so the funds have been 
transferred to the recipient's account.  The body is a `BankDepositDetails`_.
+:status 400 Bad Request: The bank replies a `BankError`_ object.
+:status 406 Not Acceptable: The request had wrong currency; the bank replies a 
`BankError`_ object.
+
+**Details:**
+
+.. _BankDepositDetails:
+.. code-block:: tsref
+
+  interface BankDepositDetails {
+
+    // Timestamp related to the transaction being made.
+    timestamp: Timestamp;
+
+    // Row id number identifying the transaction in the bank's
+    // database.
+    row_id: number;
+  }
+
+.. _BankDepositRequest:
+.. code-block:: tsref
+
+  interface BankDepositRequest {
+
+    // Authentication method used
+    auth: BankAuth;
+
+    // JSON 'amount' object. The amount the caller wants to transfer
+    // to the recipient's count
+    amount: Amount;
+
+    // Exchange base URL, used to perform tracking requests against the
+    // wire transfer ID.  Note that in the actual bank wire transfer,
+    // the schema may have to be encoded differently, i.e.
+    // "https://exchange.com/"; may become "https exchange.com" due to
+    // character set restrictions.  It is the responsibility of the
+    // wire transfer adapter to properly encode/decode the URL.
+    // Payment service providers must ensure that their URL is short
+    // enough to fit together with the wire transfer identifier into
+    // the wire transfer subject of their respective banking system.
+    exchange_url: string;
+
+    // The subject of this wire transfer.
+    subject: string;
+
+    // The sender's account identificator.  NOTE, in the current stage
+    // of development this field is _ignored_, as it's always the bank account
+    // of the logged user that plays as the "debit account".
+    // In future releases, a logged user may specify multiple bank accounts
+    // of her/his as the debit account.
+    debit_account: number;
+
+    // The recipient's account identificator
+    credit_account: number;
+
+  }
+
+.. _BankAuth:
+.. _tsref-type-BankAuth:
+.. code-block:: tsref
+
+  interface BankAuth {
+
+    // authentication type.  At this stage of development,
+    // only value "basic" is accepted in this field.
+    // The credentials must be indicated in the following HTTP
+    // headers: "X-Taler-Bank-Username" and "X-Taler-Bank-Password".
+    type: string;
+  }
+
+
+.. _BankError:
+.. code-block:: tsref
+
+  interface BankError {
+
+    // Human readable explanation of the failure.
+    error: string;
+
+    // Numeric Taler error code (`enum TALER_ErrorCode`)
+    ec: number;
+
+  }
+
+
+.. http:put:: /reject
+
+  Rejects an inbound transaction.  This can be used by the receiver of a wire 
transfer to
+  cancel that transaction, nullifying its effect.  This basically creates a 
correcting
+  entry that voids the original transaction.  Henceforth, the /history must 
show
+  the original transaction as "cancelled+" or "cancelled-" for creditor and 
debitor respectively.
+  This API is used when the exchange receives a wire transfer with an invalid 
wire
+  transfer subject that fails to decode to a public key.
+
+  **Request** The body of this request must have the format of a 
`BankCancelRequest`_.
+
+  :query auth: authentication method used.  At this stage of development, only 
value `basic` is accepted.  Note that username and password need to be given as 
request's headers.  The dedicated headers are: `X-Taler-Bank-Username` and 
`X-Taler-Bank-Password`.
+  :query row_id: row identifier of the transaction that should be cancelled.
+  :query account_number: bank account for which the incoming transfer was made 
and for which `auth` provides the authentication data.  *Currently ignored*, as 
multiple bank accounts per user are not implemented yet.
+
+  .. _BankCancelRequest:
+  .. code-block:: tsref
+
+    interface BankCancelRequest {
+
+      // Authentication method used
+      auth: BankAuth;
+
+      // The row id of the wire transfer to cancel
+      row_id: number;
+
+      // The recipient's account identificator
+      credit_account: number;
+
+    }
+
+  **Response**  In case of an error, the body is a `BankError`_ object.
+
+  :status 204 No Content: The request has been correctly handled, so the 
original transaction was voided.  The body is empty.
+  :status 400 Bad Request: The bank replies a `BankError`_ object.
+  :status 404 Not Found: The bank does not know this rowid for this account.
+
+
+.. http:get:: /history-range
+
+  Filters and returns the list of transactions in the time range specified by 
`start` and `end`
+
+  **Request**
+
+  :query auth: authentication method used.  At this stage of development, only 
value `basic` is accepted.  Note that username and password need to be given as 
request's headers.  The dedicated headers are: `X-Taler-Bank-Username` and 
`X-Taler-Bank-Password`.
+  :query start: unix timestamp indicating the oldest transaction accepted in 
the result.
+  :query end: unix timestamp indicating the youngest transaction accepted in 
the result.
+  :query direction: argument taking values `debit` or `credit`, according to 
the caller willing to receive both incoming and outgoing, only outgoing, or 
only incoming records.  Use `both` to return both directions.
+  :query cancelled: argument taking values `omit` or `show` to filter out 
rejected transactions
+  :query account_number: bank account whose history is to be returned.  
*Currently ignored*, as multiple bank accounts per user are not implemented yet.
+  :query ordering: can be `descending` or `ascending` and regulates whether 
the row are returned youger-to-older or vice versa.  Defaults to `descending`.
+
+
+  **Response**
+
+  :status 200 OK: JSON object whose field `data` is an array of type 
`BankTransaction`_.
+  :status 204 No content: in case no records exist for the targeted user.
+
+
+.. http:get:: /history
+
+  Filters and returns the list of transactions of the customer specified in 
the request.
+
+  **Request**
+
+  :query auth: authentication method used.  At this stage of development, only 
value `basic` is accepted.  Note that username and password need to be given as 
request's headers.  The dedicated headers are: `X-Taler-Bank-Username` and 
`X-Taler-Bank-Password`.
+  :query delta: returns the first `N` records younger (older) than `start` if 
`+N` (`-N`) is specified.
+  :query start: according to `delta`, only those records with row id strictly 
greater (lesser) than `start` will be returned.  This argument is optional; if 
not given, it defaults to "MAX_UINT64".
+  :query direction: argument taking values `debit` or `credit`, according to 
the caller willing to receive both incoming and outgoing, only outgoing, or 
only incoming records.  Use `both` to return both directions.
+  :query cancelled: argument taking values `omit` or `show` to filter out 
rejected transactions
+  :query account_number: bank account whose history is to be returned.  
*Currently ignored*, as multiple bank accounts per user are not implemented yet.
+  :query ordering: can be `descending` or `ascending` and regulates whether 
the row are returned youger-to-older or vice versa.  Defaults to `descending`.
+
+
+  **Response**
+
+  :status 200 OK: JSON object whose field `data` is an array of type 
`BankTransaction`_.
+  :status 204 No content: in case no records exist for the targeted user.
+
+.. _BankTransaction:
+.. code-block:: tsref
+
+  interface BankTransaction {
+
+    // identification number of the record
+    row_id: number;
+
+    // Date of the transaction
+    date: Timestamp;
+
+    // Amount transferred
+    amount: Amount;
+
+    // "-" if the transfer was outgoing, "+" if it was
+    // incoming; "cancel+" or "cancel-" if the transfer
+    // was /reject-ed by the receiver.
+    sign: string;
+
+    // Bank account number of the other party involved in the
+    // transaction.
+    counterpart: number;
+
+    // Wire transfer subject line.
+    wt_subject: string;
+
+  }
+
+..
+  The counterpart currently only points to the same bank as
+  the client using the bank.  A reasonable improvement is to
+  specify a bank URL too, so that Taler can run across multiple
+  banks.
+
+------------------------
+Interactions with wallet
+------------------------
+
+A bank and a wallet need to communicate for (1) make some elements visible
+only if the wallet is installed, (2) exchange information when the user 
withdraws
+coins.
+
+Make elements visible.
+^^^^^^^^^^^^^^^^^^^^^^
+
+This feature works via CSS injection from the wallet.  To enable it, the
+page must contain the ``<html data-taler-nojs="true">`` element, so that
+the wallet will do the injection.
+
+Whenever a element ``<x>`` needs to be visualized (hidden) if the wallet is
+installed, the special class ``taler-installed-show`` 
(``taler-installed-hide``)
+must be added to ``x``, as follows:
+
+* ``<x class="taler-installed-show">y</x>`` will make ``y`` visible.
+* ``<x class="taler-installed-hide">y</x>`` will make ``y`` visible.
+
+Clearly, a fallback page must be provided, which will be useful if the
+wallet is *not* installed.  This special page will hide any element of
+the class ``taler-install-show``; it can be downloaded at the following
+URL: ``git://taler.net/web-common/taler-fallback.css``.
+
+Withdrawing coins.
+^^^^^^^^^^^^^^^^^^
+
+After the user confirms the withdrawal, the bank must return a `202 Accepted` 
response,
+along with the following HTTP headers:
+
+* ``X-Taler-Operation: create-reserve``
+* ``X-Taler-Callback-Url: <callback_url>``; this URL will be automatically 
visited by the wallet after the user confirms the exchange.
+* ``X-Taler-Wt-Types: '["test"]'``; stringified JSON list of supported wire 
transfer types (only 'test' supported so far).
+* ``X-Taler-Amount: <amount_string>``; stringified Taler-style JSON 
:ref:`amount <amount>`.
+* ``X-Taler-Sender-Wire: <wire_details>``; stringified WireDetails_.
+* ``X-Taler-Suggested-Exchange: <URL>``; this header is optional, and 
``<URL>`` is the suggested exchange URL as given in the `SUGGESTED_EXCHANGE` 
configuration option.
+
+.. _WireDetails:
+.. code-block:: tsref
+
+  interface WireDetails {
+    type: string; // Only 'test' value admitted so far.
+    bank_uri: URL of the bank.
+    account_number: bank account number of the user attempting to withdraw.
+  }
+
+After the user confirms the exchange to withdraw coins from, the wallet will
+visit the callback URL, in order to let the user answer some security questions
+and provide all relevant data to create a reserve.
+
+.. note::
+  Currently, the bank is in charge of creating the reserve at the chosen
+  exchange.  In future, the exchange will "poll" its bank account and 
automatically
+  creating a reserve whenever it receives any funds, without any bank's
+  intervention.
+
+The callback URL implements the following API.
+
+.. http:get:: <callback_url>
+
+  **Request**
+
+  :query amount_value: integer part of the amount to be withdrawn.
+  :query amount_fraction: fractional part of the amount to be withdrawn.
+  :query amount_currency: currency of the amount to be withdrawn.
+  :query exchange: base URL of the exchange where the reserve is to be created.
+  :query reserve_pub: public key of the reserve to create.
+  :query exchange_wire_details: stringification of the chosen exchange's 
WireDetails_.
+
+  **Response**
+
+  Because the wallet is not supposed to take action according to this response,
+  the bank implementers are not required to return any particular status code 
here.
+
+  For example, our demonstrator bank always redirects the browser to the user's
+  profile page and let them know the outcome via a informational bar.
diff --git a/src/api/api-common.rst b/src/api/api-common.rst
new file mode 100644
index 0000000..8f3ae37
--- /dev/null
+++ b/src/api/api-common.rst
@@ -0,0 +1,812 @@
+..
+  This file is part of GNU TALER.
+  Copyright (C) 2014, 2015, 2016 GNUnet e.V. and INRIA
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU General Public License as published by the Free Software
+  Foundation; either version 2.1, or (at your option) any later version.
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
details.
+  You should have received a copy of the GNU Lesser General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+
+  @author Christian Grothoff
+  @author Marcello Stanisci
+
+.. _http-common:
+
+=================================
+Common Taler HTTP API Conventions
+=================================
+
+
+-------------------------
+HTTP Request and Response
+-------------------------
+
+Certain response formats are common for all requests. They are documented here
+instead of with each individual request.  Furthermore, we note that clients may
+theoretically fail to receive any response.  In this case, the client should
+verify that the Internet connection is working properly, and then proceed to
+handle the error as if an internal error (500) had been returned.
+
+.. http:any:: /*
+
+
+  **Request:**
+
+  Unless specified otherwise, HTTP requests that carry a message body must
+  have the content type `application/json`.
+
+  :reqheader Content-Type: application/json
+
+  **Response:**
+
+  :resheader Content-Type: application/json
+  :status 200: The request was successful.
+  :status 500 Internal server error:
+    This always indicates some serious internal operational error of the 
exchange,
+    such as a program bug, database problems, etc., and must not be used for
+    client-side problems.  When facing an internal server error, clients should
+    retry their request after some delay.  We recommended initially trying 
after
+    1s, twice more at randomized times within 1 minute, then the user should be
+    informed and another three retries should be scheduled within the next 24h.
+    If the error persists, a report should ultimately be made to the auditor,
+    although the auditor API for this is not yet specified.  However, as 
internal
+    server errors are always reported to the exchange operator, a good operator
+    should naturally be able to address them in a timely fashion, especially
+    within 24h.  When generating an internal server error, the exchange 
responds with
+    a JSON object containing the following fields:
+  :status 400 Bad Request: One of the arguments to the request is missing or 
malformed.
+
+  Unless specified otherwise, all error status codes (4xx and 5xx) have a 
message
+  body with an `ErrorDetail`_ JSON object.
+
+  **Details:**
+
+  .. _ErrorDetail:
+  .. _tsref-type-ErrorDetail:
+  .. code-block:: tsref
+
+    interface ErrorDetail {
+
+      // Numeric `error code <error-codes>`_ unique to the condition.
+      code: number;
+
+      // Human-readable description of the error, i.e. "missing parameter", 
"commitment violation", ...
+      // The other arguments are specific to the error value reported here.
+      error: string;
+
+      // Hint about error nature
+      hint?: string;
+
+      // Name of the parameter that was bogus (if applicable)
+      parameter?: string;
+
+      // Path to the argument that was bogus (if applicable)
+      path?: string;
+
+      // Offset of the argument that was bogus (if applicable)
+      offset?: string;
+
+      // Index of the argument that was bogus (if applicable)
+      index?: string;
+
+      // Name of the object that was bogus (if applicable)
+      object?: string;
+
+      // Name of the currency thant was problematic (if applicable)
+      currency?: string;
+
+      // Expected type (if applicable).
+      type_expected?: string;
+
+      // Type that was provided instead (if applicable).
+      type_actual?: string;
+    }
+
+
+.. _encodings-ref:
+
+----------------
+Common encodings
+----------------
+
+This section describes how certain types of values are represented throughout 
the API.
+
+.. _base32:
+.. _tsref-type-Base32:
+
+Binary Data
+^^^^^^^^^^^
+
+Binary data is generally encoded using Crockford's variant of Base32
+(http://www.crockford.com/wrmg/base32.html), except that "U" is not excluded
+but also decodes to "V" to make OCR easy.  We will still simply use the JSON
+type "base32" and the term "Crockford Base32" in the text to refer to the
+resulting encoding.
+
+.. _tsref-type-HashCode:
+
+Hash codes
+^^^^^^^^^^
+Hashcodes are strings representing base32 encoding of the respective hashed
+data. See `base32`_.
+
+Large numbers
+^^^^^^^^^^^^^
+
+Large numbers such as RSA blinding factors and 256 bit  keys, are transmitted
+as other binary data in Crockford Base32 encoding.
+
+
+.. _tsref-type-Timestamp:
+
+Timestamps
+^^^^^^^^^^
+
+Timestamps are represented in JSON as a string literal `"\\/Date(x)\\/"`,
+where `x` is the decimal representation of the number of seconds past the
+Unix Epoch (January 1, 1970).  The escaped slash (`\\/`) is interpreted in
+JSON simply as a normal slash, but distinguishes the timestamp from a normal
+string literal.  We use the type "date" in the documentation below.
+Additionally, the special strings "\\/never\\/" and "\\/forever\\/" are
+recognized to represent the end of time.
+
+
+.. _public\ key:
+
+Keys
+^^^^
+
+.. _`tsref-type-EddsaPublicKey`:
+.. _`tsref-type-EcdhePublicKey`:
+.. _`tsref-type-EcdhePrivateKey`:
+.. _`tsref-type-EddsaPrivateKey`:
+.. _`tsref-type-CoinPublicKey`:
+
+.. code-block:: tsref
+
+   // EdDSA and ECDHE public keys always point on Curve25519
+   // and represented  using the standard 256 bits Ed25519 compact format,
+   // converted to Crockford `Base32`_.
+   type EddsaPublicKey = string;
+   type EddsaPrivateKey = string;
+
+.. _`tsref-type-RsaPublicKey`:
+
+.. code-block:: tsref
+
+   // RSA public key converted to Crockford `Base32`_.
+   type RsaPublicKey = string;
+
+.. _blinded-coin:
+
+Blinded coin
+^^^^^^^^^^^^
+
+.. _`tsref-type-CoinEnvelope`:
+
+.. code-block:: tsref
+
+  // Blinded coin's `public EdDSA key <eddsa-coin-pub>`_, `base32`_ encoded
+  type CoinEnvelope = string;
+
+.. _signature:
+
+Signatures
+^^^^^^^^^^
+
+.. _`tsref-type-EddsaSignature`:
+
+.. code-block:: tsref
+
+  // EdDSA signatures are transmitted as 64-bytes `base32`_
+  // binary-encoded objects with just the R and S values (base32_ binary-only)
+  type EddsaSignature = string;
+
+
+.. _`tsref-type-RsaSignature`:
+
+.. code-block:: tsref
+
+  // `base32`_ encoded RSA signature
+  type RsaSignature = string;
+
+.. _`tsref-type-BlindedRsaSignature`:
+
+.. code-block:: tsref
+
+  // `base32`_ encoded RSA blinded signature
+  type BlindedRsaSignature = string;
+
+.. _amount:
+
+Amounts
+^^^^^^^
+
+.. _`tsref-type-Amount`:
+
+Amounts of currency are serialized as a string of the format 
`<Currency>:<DecimalAmount>`.
+Taler treats monetary amounts as fixed-precision numbers.  Unlike floating 
point numbers,
+this allows accurate representation of monetary amounts.
+
+The following constrains apply for a valid amount:
+
+1. The `<Currency>` part must be at most 12 characters long and may not 
contain a colon (`:`).
+2. The integer part of `<DecimalAmount>` may be at most 2^52
+3. the fractional part of `<DecimalAmount>` may contain at most 8 decimal 
digits.
+
+Internally, amounts are parsed into the following object:
+
+.. note::
+
+  "EUR:1.50" and "EUR:10" are is a valid amounts.  These are all invalid 
amounts: "A:B:1.5", "EUR:4503599627370501.0", "EUR:1.", "EUR:.1"
+
+.. code-block:: tsref
+
+  interface ParsedAmount {
+    // name of the currency using either a three-character ISO 4217 currency
+    // code, or a regional currency identifier starting with a "*" followed by
+    // at most 10 characters.  ISO 4217 exponents in the name are not 
supported,
+    // although the "fraction" is corresponds to an ISO 4217 exponent of 6.
+    currency: string;
+
+    // unsigned 32 bit value in the currency, note that "1" here would
+    // correspond to 1 EUR or 1 USD, depending on `currency`, not 1 cent.
+    value: number;
+
+    // unsigned 32 bit fractional value to be added to `value` representing
+    // an additional currency fraction, in units of one millionth (1e-6)
+    // of the base currency value.  For example, a fraction
+    // of 500,000 would correspond to 50 cents.
+    fraction: number;
+  }
+
+
+--------------
+Binary Formats
+--------------
+
+  .. note::
+
+     Due to the way of handling `big` numbers by some platforms (such as
+     `JavaScript`, for example), wherever the following specification mentions
+     a 64-bit value, the actual implementations are strongly advised to rely on
+     arithmetic up to 53 bits.
+
+  .. note::
+
+     Taler uses `libgnunetutil` for interfacing itself with the operating 
system,
+     doing crypto work, and other "low level" actions, therefore it is strongly
+     connected with the `GNUnet project <https://gnunet.org>`_.
+
+This section specifies the binary representation of messages used in Taler's
+protocols. The message formats are given in a C-style pseudocode notation.
+Padding is always specified explicitly, and numeric values are in network byte
+order (big endian).
+
+Amounts
+^^^^^^^
+
+Amounts of currency are always expressed in terms of a base value, a fractional
+value and the denomination of the currency:
+
+.. sourcecode:: c
+
+  struct TALER_Amount {
+    uint64_t value;
+    uint32_t fraction;
+    uint8_t currency_code[12]; // i.e. "EUR" or "USD"
+  };
+  struct TALER_AmountNBO {
+    uint64_t value;            // in network byte order
+    uint32_t fraction;         // in network byte order
+    uint8_t currency_code[12];
+  };
+
+
+Time
+^^^^
+
+In signed messages, time is represented using 64-bit big-endian values,
+denoting microseconds since the UNIX Epoch.  `UINT64_MAX` represents "never".
+
+.. sourcecode:: c
+
+  struct GNUNET_TIME_Absolute {
+    uint64_t timestamp_us;
+  };
+  struct GNUNET_TIME_AbsoluteNBO {
+    uint64_t abs_value_us__;       // in network byte order
+  };
+
+Cryptographic primitives
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+All elliptic curve operations are on Curve25519.  Public and private keys are
+thus 32 bytes, and signatures 64 bytes.  For hashing, including HKDFs, Taler
+uses 512-bit hash codes (64 bytes).
+
+.. sourcecode:: c
+
+   struct GNUNET_HashCode {
+     uint8_t hash[64];      // usually SHA-512
+   };
+
+.. _reserve-pub:
+.. sourcecode:: c
+
+   struct TALER_ReservePublicKeyP {
+     uint8_t eddsa_pub[32];
+   };
+
+.. _reserve-priv:
+.. sourcecode:: c
+
+   struct TALER_ReservePrivateKeyP {
+     uint8_t eddsa_priv[32];
+   };
+
+   struct TALER_ReserveSignatureP {
+     uint8_t eddsa_signature[64];
+   };
+
+.. _merchant-pub:
+.. sourcecode:: c
+
+   struct TALER_MerchantPublicKeyP {
+     uint8_t eddsa_pub[32];
+   };
+
+   struct TALER_MerchantPrivateKeyP {
+     uint8_t eddsa_priv[32];
+   };
+
+   struct TALER_TransferPublicKeyP {
+     uint8_t ecdhe_pub[32];
+   };
+
+   struct TALER_TransferPrivateKeyP {
+     uint8_t ecdhe_priv[32];
+   };
+
+.. _sign-key-pub:
+.. sourcecode:: c
+
+   struct TALER_ExchangePublicKeyP {
+     uint8_t eddsa_pub[32];
+   };
+
+.. _sign-key-priv:
+.. sourcecode:: c
+
+   struct TALER_ExchangePrivateKeyP {
+     uint8_t eddsa_priv[32];
+   };
+
+.. _eddsa-sig:
+.. sourcecode:: c
+
+   struct TALER_ExchangeSignatureP {
+     uint8_t eddsa_signature[64];
+   };
+
+   struct TALER_MasterPublicKeyP {
+     uint8_t eddsa_pub[32];
+   };
+
+   struct TALER_MasterPrivateKeyP {
+     uint8_t eddsa_priv[32];
+   };
+
+   struct TALER_MasterSignatureP {
+     uint8_t eddsa_signature[64];
+   };
+
+.. _eddsa-coin-pub:
+.. sourcecode:: c
+
+   union TALER_CoinSpendPublicKeyP {
+     uint8_t eddsa_pub[32];
+     uint8_t ecdhe_pub[32];
+   };
+
+.. _coin-priv:
+.. sourcecode:: c
+
+   union TALER_CoinSpendPrivateKeyP {
+     uint8_t eddsa_priv[32];
+     uint8_t ecdhe_priv[32];
+   };
+
+   struct TALER_CoinSpendSignatureP {
+     uint8_t eddsa_signature[64];
+   };
+
+   struct TALER_TransferSecretP {
+     uint8_t key[sizeof (struct GNUNET_HashCode)];
+   };
+     uint8_t key[sizeof (struct GNUNET_HashCode)];
+   };
+
+   struct TALER_EncryptedLinkSecretP {
+     uint8_t enc[sizeof (struct TALER_LinkSecretP)];
+   };
+
+.. _Signatures:
+
+Signatures
+^^^^^^^^^^
+Any piece of signed data, complies to the abstract data structure given below.
+
+.. sourcecode:: c
+
+  struct Data {
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    type1_t payload1;
+    type2_t payload2;
+    ...
+  };
+
+  /*From gnunet_crypto_lib.h*/
+  struct GNUNET_CRYPTO_EccSignaturePurpose {
+    /**
+
+    The following constrains apply for a valid amount:
+
+    * asd
+     * This field is used to express the context in
+     * which the signature is made, ensuring that a
+     * signature cannot be lifted from one part of the protocol
+     * to another. See `src/include/taler_signatures.h` within the
+     * exchange's codebase (git://taler.net/exchange)
+     */
+    uint32_t purpose;
+    /**
+     * This field equals the number of bytes being signed,
+     * namely 'sizeof (struct Data)'
+     */
+    uint32_t size;
+  };
+
+
+The following list contains all the data structure that can be signed in
+Taler. Their definition is typically found in `src/include/taler_signatures.h`,
+within the
+`exchange's codebase 
<https://docs.taler.net/global-licensing.html#exchange-repo>`_.
+
+.. _TALER_WithdrawRequestPS:
+.. sourcecode:: c
+
+  struct TALER_WithdrawRequestPS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct TALER_ReservePublicKeyP reserve_pub;
+    struct TALER_AmountNBO amount_with_fee;
+    struct TALER_AmountNBO withdraw_fee;
+    struct GNUNET_HashCode h_denomination_pub;
+    struct GNUNET_HashCode h_coin_envelope;
+  };
+
+.. _TALER_DepositRequestPS:
+.. sourcecode:: c
+
+  struct TALER_DepositRequestPS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_WALLET_COIN_DEPOSIT
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct GNUNET_HashCode h_contract_terms;
+    struct GNUNET_HashCode h_wire;
+    struct GNUNET_TIME_AbsoluteNBO timestamp;
+    struct GNUNET_TIME_AbsoluteNBO refund_deadline;
+    struct TALER_AmountNBO amount_with_fee;
+    struct TALER_AmountNBO deposit_fee;
+    struct TALER_MerchantPublicKeyP merchant;
+    union TALER_CoinSpendPublicKeyP coin_pub;
+  };
+
+.. _TALER_DepositConfirmationPS:
+.. sourcecode:: c
+
+  struct TALER_DepositConfirmationPS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_WALLET_CONFIRM_DEPOSIT
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct GNUNET_HashCode h_contract_terms;
+    struct GNUNET_HashCode h_wire;
+    struct GNUNET_TIME_AbsoluteNBO timestamp;
+    struct GNUNET_TIME_AbsoluteNBO refund_deadline;
+    struct TALER_AmountNBO amount_without_fee;
+    union TALER_CoinSpendPublicKeyP coin_pub;
+    struct TALER_MerchantPublicKeyP merchant;
+  };
+
+.. _TALER_RefreshMeltCoinAffirmationPS:
+.. sourcecode:: c
+
+  struct TALER_RefreshMeltCoinAffirmationPS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_WALLET_COIN_MELT
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct GNUNET_HashCode session_hash;
+    struct TALER_AmountNBO amount_with_fee;
+    struct TALER_AmountNBO melt_fee;
+    union TALER_CoinSpendPublicKeyP coin_pub;
+  };
+
+.. _TALER_RefreshMeltConfirmationPS:
+.. sourcecode:: c
+
+  struct TALER_RefreshMeltConfirmationPS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct GNUNET_HashCode session_hash;
+    uint16_t noreveal_index;
+  };
+
+.. _TALER_ExchangeSigningKeyValidityPS:
+.. sourcecode:: c
+
+  struct TALER_ExchangeSigningKeyValidityPS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct TALER_MasterPublicKeyP master_public_key;
+    struct GNUNET_TIME_AbsoluteNBO start;
+    struct GNUNET_TIME_AbsoluteNBO expire;
+    struct GNUNET_TIME_AbsoluteNBO end;
+    struct TALER_ExchangePublicKeyP signkey_pub;
+  };
+
+  struct TALER_ExchangeKeySetPS {
+      /**
+       * purpose.purpose = TALER_SIGNATURE_EXCHANGE_KEY_SET
+       */
+      struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+      struct GNUNET_TIME_AbsoluteNBO list_issue_date;
+      struct GNUNET_HashCode hc;
+  };
+
+.. _TALER_DenominationKeyValidityPS:
+.. sourcecode:: c
+
+  struct TALER_DenominationKeyValidityPS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct TALER_MasterPublicKeyP master;
+    struct GNUNET_TIME_AbsoluteNBO start;
+    struct GNUNET_TIME_AbsoluteNBO expire_withdraw;
+    struct GNUNET_TIME_AbsoluteNBO expire_spend;
+    struct GNUNET_TIME_AbsoluteNBO expire_legal;
+    struct TALER_AmountNBO value;
+    struct TALER_AmountNBO fee_withdraw;
+    struct TALER_AmountNBO fee_deposit;
+    struct TALER_AmountNBO fee_refresh;
+    struct GNUNET_HashCode denom_hash;
+  };
+
+.. _TALER_MasterWireDetailsPS:
+.. sourcecode:: c
+
+  struct TALER_MasterWireDetailsPS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_MASTER_WIRE_DETAILS
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct GNUNET_HashCode h_wire_details;
+  };
+
+
+.. _TALER_MasterWireFeePS:
+.. sourcecode:: c
+
+  struct TALER_MasterWireFeePS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_MASTER_WIRE_FEES
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct GNUNET_HashCode h_wire_method;
+    struct GNUNET_TIME_AbsoluteNBO start_date;
+    struct GNUNET_TIME_AbsoluteNBO end_date;
+    struct TALER_AmountNBO wire_fee;
+    struct TALER_AmountNBO closing_fee;
+  };
+
+.. _TALER_DepositTrackPS:
+.. sourcecode:: c
+
+  struct TALER_DepositTrackPS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_MASTER_SEPA_DETAILS || 
TALER_SIGNATURE_MASTER_TEST_DETAILS
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct GNUNET_HashCode h_contract_terms;
+    struct GNUNET_HashCode h_wire;
+    struct TALER_MerchantPublicKeyP merchant;
+    struct TALER_CoinSpendPublicKeyP coin_pub;
+  };
+
+.. _TALER_WireDepositDetailP:
+.. sourcecode:: c
+
+  struct TALER_WireDepositDetailP {
+    struct GNUNET_HashCode h_contract_terms;
+    struct GNUNET_TIME_AbsoluteNBO execution_time;
+    struct TALER_CoinSpendPublicKeyP coin_pub;
+    struct TALER_AmountNBO deposit_value;
+    struct TALER_AmountNBO deposit_fee;
+  };
+
+
+.. _TALER_WireDepositDataPS:
+.. sourcecode:: c
+
+  struct TALER_WireDepositDataPS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct TALER_AmountNBO total;
+    struct TALER_AmountNBO wire_fee;
+    struct TALER_MerchantPublicKeyP merchant_pub;
+    struct GNUNET_HashCode h_wire;
+    struct GNUNET_HashCode h_details;
+  };
+
+.. _TALER_ExchangeKeyValidityPS:
+.. sourcecode:: c
+
+  struct TALER_ExchangeKeyValidityPS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct GNUNET_HashCode auditor_url_hash;
+    struct TALER_MasterPublicKeyP master;
+    struct GNUNET_TIME_AbsoluteNBO start;
+    struct GNUNET_TIME_AbsoluteNBO expire_withdraw;
+    struct GNUNET_TIME_AbsoluteNBO expire_spend;
+    struct GNUNET_TIME_AbsoluteNBO expire_legal;
+    struct TALER_AmountNBO value;
+    struct TALER_AmountNBO fee_withdraw;
+    struct TALER_AmountNBO fee_deposit;
+    struct TALER_AmountNBO fee_refresh;
+    struct GNUNET_HashCode denom_hash;
+  };
+
+.. _TALER_PaymentResponsePS:
+.. sourcecode:: c
+
+  struct PaymentResponsePS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_MERCHANT_PAYMENT_OK
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct GNUNET_HashCode h_contract_terms;
+  };
+
+.. _TALER_ContractPS:
+.. sourcecode:: c
+
+  struct TALER_ContractPS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_MERCHANT_CONTRACT
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct TALER_AmountNBO total_amount;
+    struct TALER_AmountNBO max_fee;
+    struct GNUNET_HashCode h_contract_terms;
+    struct TALER_MerchantPublicKeyP merchant_pub;
+  };
+
+.. _TALER_ConfirmWirePS:
+.. sourcecode:: c
+
+  struct TALER_ConfirmWirePS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct GNUNET_HashCode h_wire;
+    struct GNUNET_HashCode h_contract_terms;
+    struct TALER_WireTransferIdentifierRawP wtid;
+    struct TALER_CoinSpendPublicKeyP coin_pub;
+    struct GNUNET_TIME_AbsoluteNBO execution_time;
+    struct TALER_AmountNBO coin_contribution;
+  };
+
+.. _TALER_RefundRequestPS:
+.. sourcecode:: c
+
+  struct TALER_RefundRequestPS {
+    /**
+     *  purpose.purpose = TALER_SIGNATURE_MERCHANT_REFUND
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct GNUNET_HashCode h_contract_terms;
+    struct TALER_CoinSpendPublicKeyP coin_pub;
+    struct TALER_MerchantPublicKeyP merchant;
+    uint64_t rtransaction_id;
+    struct TALER_AmountNBO refund_amount;
+    struct TALER_AmountNBO refund_fee;
+  };
+
+  struct TALER_MerchantRefundConfirmationPS {
+    /**
+     *  purpose.purpose = TALER_SIGNATURE_MERCHANT_REFUND_OK
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    /**
+     * Hash of the order ID (a string), hashed without the 0-termination.
+     */
+    struct GNUNET_HashCode h_order_id;
+  };
+
+
+.. _TALER_PaybackRequestPS:
+.. sourcecode:: c
+
+  struct TALER_PaybackRequestPS {
+    /**
+     *  purpose.purpose = TALER_SIGNATURE_WALLET_COIN_PAYBACK
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct TALER_CoinSpendPublicKeyP coin_pub;
+    struct GNUNET_HashCode h_denom_pub;
+    struct TALER_DenominationBlindingKeyP coin_blind;
+  };
+
+
+.. _TALER_PaybackConfirmationPS:
+.. sourcecode:: c
+
+  struct TALER_PaybackConfirmationPS {
+    /**
+     *  purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct GNUNET_TIME_AbsoluteNBO timestamp;
+    struct TALER_AmountNBO payback_amount;
+    struct TALER_CoinSpendPublicKeyP coin_pub;
+    struct TALER_ReservePublicKeyP reserve_pub;
+  };
+
+
+.. _TALER_ReserveCloseConfirmationPS:
+.. sourcecode:: c
+
+  struct TALER_ReserveCloseConfirmationPS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct GNUNET_TIME_AbsoluteNBO timestamp;
+    struct TALER_AmountNBO closing_amount;
+    struct TALER_ReservePublicKeyP reserve_pub;
+    struct GNUNET_HashCode h_wire;
+  };
+
+.. _TALER_CoinLinkSignaturePS:
+.. sourcecode:: c
+
+  struct TALER_CoinLinkSignaturePS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_WALLET_COIN_LINK
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct GNUNET_HashCode h_denom_pub;
+    struct TALER_CoinSpendPublicKeyP old_coin_pub;
+    struct TALER_TransferPublicKeyP transfer_pub;
+    struct GNUNET_HashCode coin_envelope_hash;
+  };
diff --git a/src/api/api-error.rst b/src/api/api-error.rst
new file mode 100644
index 0000000..61716b7
--- /dev/null
+++ b/src/api/api-error.rst
@@ -0,0 +1,1204 @@
+..
+  This file is part of GNU TALER.
+  Copyright (C) 2014, 2015, 2016 GNUnet e.V. and INRIA
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU General Public License as published by the Free Software
+  Foundation; either version 2.1, or (at your option) any later version.
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
details.
+  You should have received a copy of the GNU Lesser General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+
+  @author Marcello Stanisci
+
+..
+  The reason to have a dedicate page for error codes was due to a buggy
+  behaviour in pages cross-linking:  was not possible from other pages to
+  reference the '_error-codes' label (see just below) if we kept in 
api-common.rst
+  (which is the best place to place this error codes list).
+
+-----------
+Error Codes
+-----------
+
+The following list shows error codes defined in
+`<EXCHANGE-REPO>/src/include/taler_error_codes.h 
<https://git.taler.net/exchange.git/tree/src/include/taler_error_codes.h>`_
+
+.. _error-codes:
+.. code-block:: c
+
+  /**
+   * Enumeration with all possible Taler error codes.
+   */
+  enum TALER_ErrorCode {
+    
+    /**
+     * Special code to indicate no error (or no "code" present).
+     */
+    TALER_EC_NONE = 0,
+  
+    /**
+     * Special code to indicate that a non-integer error code was
+     * returned in the JSON response.
+     */
+    TALER_EC_INVALID = 1,
+  
+    /**
+     * The response we got from the server was not even in JSON format.
+     */
+    TALER_EC_INVALID_RESPONSE = 2,
+  
+    /**
+     * Generic implementation error: this function was not yet implemented.
+     */
+    TALER_EC_NOT_IMPLEMENTED = 3,
+    
+    /* ********** generic error codes ************* */
+  
+    /**
+     * The exchange failed to even just initialize its connection to the
+     * database.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_DB_SETUP_FAILED = 1001,
+  
+    /**
+     * The exchange encountered an error event to just start
+     * the database transaction.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_DB_START_FAILED = 1002,
+  
+    /**
+     * The exchange encountered an error event to commit
+     * the database transaction (hard, unrecoverable error).
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_DB_COMMIT_FAILED_HARD = 1003,
+  
+    /**
+     * The exchange encountered an error event to commit
+     * the database transaction, even after repeatedly
+     * retrying it there was always a conflicting transaction.
+     * (This indicates a repeated serialization error; should
+     * only happen if some client maliciously tries to create
+     * conflicting concurrent transactions.)
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_DB_COMMIT_FAILED_ON_RETRY = 1004,
+  
+      /**
+     * The exchange had insufficient memory to parse the request. This
+     * response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_PARSER_OUT_OF_MEMORY = 1005,
+  
+    /**
+     * The JSON in the client's request to the exchange was malformed.
+     * (Generic parse error).
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_JSON_INVALID = 1006,
+  
+    /**
+     * The JSON in the client's request to the exchange was malformed.
+     * Details about the location of the parse error are provided.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_JSON_INVALID_WITH_DETAILS = 1007,
+  
+    /**
+     * A required parameter in the request to the exchange was missing.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_PARAMETER_MISSING = 1008,
+  
+    /**
+     * A parameter in the request to the exchange was malformed.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_PARAMETER_MALFORMED = 1009,
+  
+    /* ********** request-specific error codes ************* */
+  
+    /**
+     * The given reserve does not have sufficient funds to admit the
+     * requested withdraw operation at this time.  The response includes
+     * the current "balance" of the reserve as well as the transaction
+     * "history" that lead to this balance.  This response is provided
+     * with HTTP status code MHD_HTTP_FORBIDDEN.
+     */
+    TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS = 1100,
+  
+    /**
+     * The exchange has no information about the "reserve_pub" that
+     * was given.
+     * This response is provided with HTTP status code MHD_HTTP_NOT_FOUND.
+     */
+    TALER_EC_WITHDRAW_RESERVE_UNKNOWN = 1101,
+  
+    /**
+     * The amount to withdraw together with the fee exceeds the
+     * numeric range for Taler amounts.  This is not a client
+     * failure, as the coin value and fees come from the exchange's
+     * configuration.
+     * This response is provided with HTTP status code MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_WITHDRAW_AMOUNT_FEE_OVERFLOW = 1102,
+  
+    /**
+     * All of the deposited amounts into this reserve total up to a
+     * value that is too big for the numeric range for Taler amounts.
+     * This is not a client failure, as the transaction history comes
+     * from the exchange's configuration.  This response is provided
+     * with HTTP status code MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_WITHDRAW_AMOUNT_DEPOSITS_OVERFLOW = 1103,
+  
+    /**
+     * For one of the historic withdrawals from this reserve, the
+     * exchange could not find the denomination key.
+     * This is not a client failure, as the transaction history comes
+     * from the exchange's configuration.  This response is provided
+     * with HTTP status code MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_WITHDRAW_HISTORIC_DENOMINATION_KEY_NOT_FOUND = 1104,
+  
+    /**
+     * All of the withdrawals from reserve total up to a
+     * value that is too big for the numeric range for Taler amounts.
+     * This is not a client failure, as the transaction history comes
+     * from the exchange's configuration.  This response is provided
+     * with HTTP status code MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_WITHDRAW_AMOUNT_WITHDRAWALS_OVERFLOW = 1105,
+  
+    /**
+     * The exchange somehow knows about this reserve, but there seem to
+     * have been no wire transfers made.  This is not a client failure,
+     * as this is a database consistency issue of the exchange.  This
+     * response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_WITHDRAW_RESERVE_WITHOUT_WIRE_TRANSFER = 1106,
+  
+    /**
+     * The exchange failed to create the signature using the
+     * denomination key.  This response is provided with HTTP status
+     * code MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_WITHDRAW_SIGNATURE_FAILED = 1107,
+  
+    /**
+     * The exchange failed to store the withdraw operation in its
+     * database.  This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_WITHDRAW_DB_STORE_ERROR = 1108,
+  
+    /**
+     * The exchange failed to check against historic withdraw data from
+     * database (as part of ensuring the idempotency of the operation).
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_WITHDRAW_DB_FETCH_ERROR = 1109,
+  
+    /**
+     * The exchange is not aware of the denomination key
+     * the wallet requested for the withdrawal.
+     * This response is provided
+     * with HTTP status code MHD_HTTP_NOT_FOUND.
+     */
+    TALER_EC_WITHDRAW_DENOMINATION_KEY_NOT_FOUND = 1110,
+  
+    /**
+     * The signature of the reserve is not valid.  This response is
+     * provided with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_WITHDRAW_RESERVE_SIGNATURE_INVALID = 1111,
+  
+    /**
+     * The exchange failed to obtain the transaction history of the
+     * given reserve from the database while generating an insufficient
+     * funds errors.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_WITHDRAW_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS = 1112,
+  
+    /**
+     * When computing the reserve history, we ended up with a negative
+     * overall balance, which should be impossible.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_WITHDRAW_RESERVE_HISTORY_IMPOSSIBLE = 1113,
+  
+    /**
+     * The exchange failed to obtain the transaction history of the
+     * given reserve from the database.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_RESERVE_STATUS_DB_ERROR = 1150,
+  
+  
+    /**
+     * The respective coin did not have sufficient residual value
+     * for the /deposit operation (i.e. due to double spending).
+     * The "history" in the respose provides the transaction history
+     * of the coin proving this fact.  This response is provided
+     * with HTTP status code MHD_HTTP_FORBIDDEN.
+     */
+    TALER_EC_DEPOSIT_INSUFFICIENT_FUNDS = 1200,
+  
+    /**
+     * The exchange failed to obtain the transaction history of the
+     * given coin from the database (this does not happen merely because
+     * the coin is seen by the exchange for the first time).
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_DEPOSIT_HISTORY_DB_ERROR = 1201,
+  
+    /**
+     * The exchange failed to store the /depost information in the
+     * database.  This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_DEPOSIT_STORE_DB_ERROR = 1202,
+  
+    /**
+     * The exchange database is unaware of the denomination key that
+     * signed the coin (however, the exchange process is; this is not
+     * supposed to happen; it can happen if someone decides to purge the
+     * DB behind the back of the exchange process).  Hence the deposit
+     * is being refused.  This response is provided with HTTP status
+     * code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_DEPOSIT_DB_DENOMINATION_KEY_UNKNOWN = 1203,
+  
+    /**
+     * The exchange database is unaware of the denomination key that
+     * signed the coin (however, the exchange process is; this is not
+     * supposed to happen; it can happen if someone decides to purge the
+     * DB behind the back of the exchange process).  Hence the deposit
+     * is being refused.  This response is provided with HTTP status
+     * code MHD_HTTP_NOT_FOUND.
+     */
+    TALER_EC_DEPOSIT_DENOMINATION_KEY_UNKNOWN = 1204,
+  
+    /**
+     * The signature of the coin is not valid.  This response is
+     * provided with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_DEPOSIT_COIN_SIGNATURE_INVALID = 1205,
+  
+    /**
+     * The signature of the denomination key over the coin is not valid.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_DEPOSIT_DENOMINATION_SIGNATURE_INVALID = 1206,
+  
+    /**
+     * The stated value of the coin after the deposit fee is subtracted
+     * would be negative.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE = 1207,
+  
+    /**
+     * The stated refund deadline is after the wire deadline.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE = 1208,
+  
+    /**
+     * The exchange does not recognize the validity of or support the
+     * given wire format type.
+     * This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_TYPE = 1209,
+  
+    /**
+     * The exchange failed to canonicalize and hash the given wire format.
+     * This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_JSON = 1210,
+  
+    /**
+     * The hash of the given wire address does not match the hash
+     * specified in the contract.
+     * This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT = 1211,
+  
+    /**
+     * The exchange failed to obtain the transaction history of the
+     * given coin from the database while generating an insufficient
+     * funds errors.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_DEPOSIT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS = 1212,
+  
+    /**
+     * The exchange detected that the given account number
+     * is invalid for the selected wire format type.
+     * This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_ACCOUNT_NUMBER = 1213,
+  
+    /**
+     * The signature over the given wire details is invalid.
+     * This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_SIGNATURE = 1214,
+  
+    /**
+     * The bank specified in the wire transfer format is not supported
+     * by this exchange.
+     * This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_BANK = 1215,
+  
+    /**
+     * No wire format type was specified in the JSON wire format
+     * details.
+     * This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_TYPE_MISSING = 1216,
+  
+    /**
+     * The given wire format type is not supported by this
+     * exchange.
+     * This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_TYPE_UNSUPPORTED = 1217,
+  
+  
+    /**
+     * The respective coin did not have sufficient residual value
+     * for the /refresh/melt operation.  The "history" in this
+     * response provdes the "residual_value" of the coin, which may
+     * be less than its "original_value".  This response is provided
+     * with HTTP status code MHD_HTTP_FORBIDDEN.
+     */
+    TALER_EC_REFRESH_MELT_INSUFFICIENT_FUNDS = 1300,
+  
+    /**
+     * The exchange is unaware of the denomination key that was
+     * used to sign the melted coin.  This response is provided
+     * with HTTP status code MHD_HTTP_NOT_FOUND.
+     */
+    TALER_EC_REFRESH_MELT_DENOMINATION_KEY_NOT_FOUND = 1301,
+  
+    /**
+     * The exchange had an internal error reconstructing the
+     * transaction history of the coin that was being melted.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_REFRESH_MELT_COIN_HISTORY_COMPUTATION_FAILED = 1302,
+  
+    /**
+     * The exchange failed to check against historic melt data from
+     * database (as part of ensuring the idempotency of the operation).
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_REFRESH_MELT_DB_FETCH_ERROR = 1303,
+  
+    /**
+     * The exchange failed to store session data in the
+     * database.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_REFRESH_MELT_DB_STORE_SESSION_ERROR = 1304,
+  
+    /**
+     * The exchange failed to store refresh order data in the
+     * database.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_REFRESH_MELT_DB_STORE_ORDER_ERROR = 1305,
+  
+    /**
+     * The exchange failed to store commit data in the
+     * database.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_REFRESH_MELT_DB_STORE_COMMIT_ERROR = 1306,
+  
+    /**
+     * The exchange failed to store transfer keys in the
+     * database.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_REFRESH_MELT_DB_STORE_TRANSFER_ERROR = 1307,
+  
+    /**
+     * The exchange is unaware of the denomination key that was
+     * requested for one of the fresh coins.  This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_REFRESH_MELT_FRESH_DENOMINATION_KEY_NOT_FOUND = 1308,
+  
+    /**
+     * The exchange encountered a numeric overflow totaling up
+     * the cost for the refresh operation.  This response is provided
+     * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_REFRESH_MELT_COST_CALCULATION_OVERFLOW = 1309,
+  
+    /**
+     * During the transaction phase, the exchange could suddenly
+     * no longer find the denomination key that was
+     * used to sign the melted coin.  This response is provided
+     * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_REFRESH_MELT_DB_DENOMINATION_KEY_NOT_FOUND = 1310,
+  
+    /**
+     * The exchange encountered melt fees exceeding the melted
+     * coin's contribution.  This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_REFRESH_MELT_FEES_EXCEED_CONTRIBUTION = 1311,
+  
+    /**
+     * The exchange's cost calculation does not add up to the
+     * melt fees specified in the request.  This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_REFRESH_MELT_FEES_MISSMATCH = 1312,
+  
+    /**
+     * The denomination key signature on the melted coin is invalid.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_REFRESH_MELT_DENOMINATION_SIGNATURE_INVALID = 1313,
+  
+    /**
+     * The exchange's cost calculation shows that the melt amount
+     * is below the costs of the transaction.  This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_REFRESH_MELT_AMOUNT_INSUFFICIENT = 1314,
+  
+    /**
+     * The signature made with the coin to be melted is invalid.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_REFRESH_MELT_COIN_SIGNATURE_INVALID = 1315,
+  
+    /**
+     * The size of the cut-and-choose dimension of the
+     * blinded coins request does not match #TALER_CNC_KAPPA.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_REFRESH_MELT_CNC_COIN_ARRAY_SIZE_INVALID = 1316,
+  
+    /**
+     * The size of the cut-and-choose dimension of the
+     * transfer keys request does not match #TALER_CNC_KAPPA.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_REFRESH_MELT_CNC_TRANSFER_ARRAY_SIZE_INVALID = 1317,
+  
+    /**
+     * The exchange failed to obtain the transaction history of the
+     * given coin from the database while generating an insufficient
+     * funds errors.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_REFRESH_MELT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS = 1318,
+  
+    /**
+     * The provided transfer keys do not match up with the
+     * original commitment.  Information about the original
+     * commitment is included in the response.  This response is
+     * provided with HTTP status code MHD_HTTP_CONFLICT.
+     */
+    TALER_EC_REFRESH_REVEAL_COMMITMENT_VIOLATION = 1350,
+  
+    /**
+     * Failed to blind the envelope to reconstruct the blinded
+     * coins for revealation checks.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_REFRESH_REVEAL_BLINDING_ERROR = 1351,
+  
+    /**
+     * Failed to produce the blinded signatures over the coins
+     * to be returned.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_REFRESH_REVEAL_SIGNING_ERROR = 1352,
+  
+    /**
+     * The exchange is unaware of the refresh sessino specified in
+     * the request.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN = 1353,
+  
+    /**
+     * The exchange failed to retrieve valid session data from the
+     * database.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR = 1354,
+  
+    /**
+     * The exchange failed to retrieve order data from the
+     * database.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_REFRESH_REVEAL_DB_FETCH_ORDER_ERROR = 1355,
+  
+    /**
+     * The exchange failed to retrieve transfer keys from the
+     * database.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_REFRESH_REVEAL_DB_FETCH_TRANSFER_ERROR = 1356,
+  
+    /**
+     * The exchange failed to retrieve commitment data from the
+     * database.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_ERROR.
+     */
+    TALER_EC_REFRESH_REVEAL_DB_FETCH_COMMIT_ERROR = 1357,
+  
+    /**
+     * The size of the cut-and-choose dimension of the
+     * private transfer keys request does not match #TALER_CNC_KAPPA - 1.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_REFRESH_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID = 1358,
+  
+  
+    /**
+     * The coin specified in the link request is unknown to the exchange.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_NOT_FOUND.
+     */
+    TALER_EC_REFRESH_LINK_COIN_UNKNOWN = 1400,
+  
+  
+    /**
+     * The exchange knows literally nothing about the coin we were asked
+     * to refund. But without a transaction history, we cannot issue a
+     * refund.  This is kind-of OK, the owner should just refresh it
+     * directly without executing the refund.  This response is provided
+     * with HTTP status code MHD_HTTP_NOT_FOUND.
+     */
+    TALER_EC_REFUND_COIN_NOT_FOUND = 1500,
+  
+    /**
+     * We could not process the refund request as the coin's transaction
+     * history does not permit the requested refund at this time.  The
+     * "history" in the response proves this.  This response is provided
+     * with HTTP status code MHD_HTTP_CONFLICT.
+     */
+    TALER_EC_REFUND_CONFLICT = 1501,
+  
+    /**
+     * The exchange knows about the coin we were asked to refund, but
+     * not about the specific /deposit operation.  Hence, we cannot
+     * issue a refund (as we do not know if this merchant public key is
+     * authorized to do a refund).  This response is provided with HTTP
+     * status code MHD_HTTP_NOT_FOUND.
+     */
+    TALER_EC_REFUND_DEPOSIT_NOT_FOUND = 1503,
+  
+    /**
+     * The currency specified for the refund is different from
+     * the currency of the coin.  This response is provided with HTTP
+     * status code MHD_HTTP_PRECONDITION_FAILED.
+     */
+    TALER_EC_REFUND_CURRENCY_MISSMATCH = 1504,
+  
+    /**
+     * When we tried to check if we already paid out the coin, the
+     * exchange's database suddenly disagreed with data it previously
+     * provided (internal inconsistency).
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_REFUND_DB_INCONSISTENT = 1505,
+  
+    /**
+     * The exchange can no longer refund the customer/coin as the
+     * money was already transferred (paid out) to the merchant.
+     * (It should be past the refund deadline.)
+     * This response is provided with HTTP status code
+     * MHD_HTTP_GONE.
+     */
+    TALER_EC_REFUND_MERCHANT_ALREADY_PAID = 1506,
+  
+    /**
+     * The amount the exchange was asked to refund exceeds
+     * (with fees) the total amount of the deposit (including fees).
+     * This response is provided with HTTP status code
+     * MHD_HTTP_PRECONDITION_FAILED.
+     */
+    TALER_EC_REFUND_INSUFFICIENT_FUNDS = 1507,
+  
+    /**
+     * The exchange failed to recover information about the
+     * denomination key of the refunded coin (even though it
+     * recognizes the key).  Hence it could not check the fee
+     * strucutre.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_REFUND_DENOMINATION_KEY_NOT_FOUND = 1508,
+  
+    /**
+     * The refund fee specified for the request is lower than
+     * the refund fee charged by the exchange for the given
+     * denomination key of the refunded coin.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_REFUND_FEE_TOO_LOW = 1509,
+  
+    /**
+     * The exchange failed to store the refund information to
+     * its database.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_REFUND_STORE_DB_ERROR = 1510,
+  
+    /**
+     * The refund fee is specified in a different currency
+     * than the refund amount.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_REFUND_FEE_CURRENCY_MISSMATCH = 1511,
+  
+    /**
+     * The refunded amount is smaller than the refund fee,
+     * which would result in a negative refund.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_REFUND_FEE_ABOVE_AMOUNT = 1512,
+  
+    /**
+     * The signature of the merchant is invalid.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_REFUND_MERCHANT_SIGNATURE_INVALID = 1513,
+  
+  
+    /**
+     * The wire format specified in the "sender_account_details"
+     * is not understood or not supported by this exchange.
+     * Returned with an HTTP status code of MHD_HTTP_NOT_FOUND.
+     * (As we did not find an interpretation of the wire format.)
+     */
+    TALER_EC_ADMIN_ADD_INCOMING_WIREFORMAT_UNSUPPORTED = 1600,
+  
+    /**
+     * The currency specified in the "amount" parameter is not
+     * supported by this exhange.  Returned with an HTTP status
+     * code of MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_ADMIN_ADD_INCOMING_CURRENCY_UNSUPPORTED = 1601,
+  
+    /**
+     * The exchange failed to store information about the incoming
+     * transfer in its database.  This response is provided with HTTP
+     * status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_ADMIN_ADD_INCOMING_DB_STORE = 1602,
+  
+    /**
+     * The exchange encountered an error (that is not about not finding
+     * the wire transfer) trying to lookup a wire transfer identifier
+     * in the database.  This response is provided with HTTP
+     * status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED = 1700,
+  
+    /**
+     * The exchange found internally inconsistent data when resolving a
+     * wire transfer identifier in the database.  This response is
+     * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TRACK_TRANSFER_DB_INCONSISTENT = 1701,
+  
+    /**
+     * The exchange did not find information about the specified
+     * wire transfer identifier in the database.  This response is
+     * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+     */
+    TALER_EC_TRACK_TRANSFER_WTID_NOT_FOUND = 1702,
+  
+  
+    /**
+     * The exchange found internally inconsistent fee data when
+     * resolving a transaction in the database.  This
+     * response is provided with HTTP status code
+     * MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TRACK_TRANSACTION_DB_FEE_INCONSISTENT = 1800,
+  
+    /**
+     * The exchange encountered an error (that is not about not finding
+     * the transaction) trying to lookup a transaction
+     * in the database.  This response is provided with HTTP
+     * status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TRACK_TRANSACTION_DB_FETCH_FAILED = 1801,
+  
+    /**
+     * The exchange did not find information about the specified
+     * transaction in the database.  This response is
+     * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+     */
+    TALER_EC_TRACK_TRANSACTION_NOT_FOUND = 1802,
+  
+    /**
+     * The exchange failed to identify the wire transfer of the
+     * transaction (or information about the plan that it was supposed
+     * to still happen in the future).  This response is provided with
+     * HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TRACK_TRANSACTION_WTID_RESOLUTION_ERROR = 1803,
+  
+    /**
+     * The signature of the merchant is invalid.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_TRACK_TRANSACTION_MERCHANT_SIGNATURE_INVALID = 1804,
+  
+  
+    /* *********** Merchant backend error codes ********* */
+  
+    /**
+     * The backend could not find the merchant instance specified
+     * in the request.   This response is
+     * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+     */
+    TALER_EC_CONTRACT_INSTANCE_UNKNOWN = 2000,
+  
+    /**
+     * The exchange failed to provide a meaningful response
+     * to a /deposit request.  This response is provided
+     * with HTTP status code MHD_HTTP_SERVICE_UNAVAILABLE.
+     */
+    TALER_EC_PAY_EXCHANGE_FAILED = 2101,
+  
+    /**
+     * The merchant failed to commit the exchanges' response to
+     * a /deposit request to its database.  This response is provided
+     * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_PAY_DB_STORE_PAY_ERROR = 2102,
+  
+    /**
+     * The specified exchange is not supported/trusted by
+     * this merchant.  This response is provided
+     * with HTTP status code MHD_HTTP_PRECONDITION_FAILED.
+     */
+    TALER_EC_PAY_EXCHANGE_REJECTED = 2103,
+  
+    /**
+     * The denomination key used for payment is not listed among the
+     * denomination keys of the exchange.  This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_PAY_DENOMINATION_KEY_NOT_FOUND = 2104,
+  
+    /**
+     * The denomination key used for payment is not audited by an
+     * auditor approved by the merchant.  This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_PAY_DENOMINATION_KEY_AUDITOR_FAILURE = 2105,
+  
+    /**
+     * There was an integer overflow totaling up the amounts or
+     * deposit fees in the payment.  This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_PAY_AMOUNT_OVERFLOW = 2106,
+  
+    /**
+     * The deposit fees exceed the total value of the payment.
+     * This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_PAY_FEES_EXCEED_PAYMENT = 2107,
+  
+    /**
+     * After considering deposit fees, the payment is insufficient
+     * to satisfy the required amount for the contract.
+     * This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_PAY_PAYMENT_INSUFFICIENT_DUE_TO_FEES = 2108,
+  
+    /**
+     * While the merchant is happy to cover all applicable deposit fees,
+     * the payment is insufficient to satisfy the required amount for
+     * the contract.  This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_PAY_PAYMENT_INSUFFICIENT = 2109,
+  
+    /**
+     * The signature over the contract of one of the coins
+     * was invalid. This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_PAY_COIN_SIGNATURE_INVALID = 2110,
+  
+    /**
+     * We failed to contact the exchange for the /pay request.
+     * This response is provided
+     * with HTTP status code MHD_HTTP_SERVICE_UNAVAILABLE.
+     */
+    TALER_EC_PAY_EXCHANGE_TIMEOUT = 2111,
+  
+    /**
+     * The backend could not find the merchant instance specified
+     * in the request.   This response is
+     * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+     */
+    TALER_EC_PAY_INSTANCE_UNKNOWN = 2112,
+  
+    /**
+     * The signature over the contract of the merchant
+     * was invalid. This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_PAY_MERCHANT_SIGNATURE_INVALID = 2113,
+  
+    /**
+     * The refund deadline was after the transfer deadline.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_PAY_REFUND_DEADLINE_PAST_WIRE_TRANSFER_DEADLINE = 2114,
+  
+    /**
+     * The request fails to provide coins for the payment.
+     * This response is provided with HTTP status code
+     * MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_PAY_COINS_ARRAY_EMPTY = 2115,
+  
+    /**
+     * The merchant failed to fetch the merchant's previous state with
+     * respect to a /pay request from its database.  This response is
+     * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_PAY_DB_FETCH_PAY_ERROR = 2116,
+  
+    /**
+     * The merchant failed to fetch the merchant's previous state with
+     * respect to transactions from its database.  This response is
+     * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_PAY_DB_FETCH_TRANSACTION_ERROR = 2117,
+  
+    /**
+     * The transaction ID was used for a conflicing transaction before.
+     * This response is
+     * provided with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_PAY_DB_TRANSACTION_ID_CONFLICT = 2118,
+  
+    /**
+     * The merchant failed to store the merchant's state with
+     * respect to the transaction in its database.  This response is
+     * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_PAY_DB_STORE_TRANSACTION_ERROR = 2119,
+  
+    /**
+     * The exchange failed to provide a valid response to
+     * the merchant's /keys request.
+     * This response is provided
+     * with HTTP status code MHD_HTTP_SERVICE_UNAVAILABLE.
+     */
+    TALER_EC_PAY_EXCHANGE_KEYS_FAILURE = 2120,
+  
+    /**
+     * The payment is too late, the offer has expired.
+     * This response is
+     * provided with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_PAY_OFFER_EXPIRED = 2121,
+  
+  
+    /**
+     * Integer overflow with sepcified timestamp argument detected.
+     * This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_HISTORY_TIMESTAMP_OVERFLOW = 2200,
+  
+    /**
+     * Failed to retrieve history from merchant database.
+     * This response is provided
+     * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_HISTORY_DB_FETCH_ERROR = 2201,
+  
+    /**
+     * We failed to contact the exchange for the /track/transaction
+     * request.  This response is provided with HTTP status code
+     * MHD_HTTP_SERVICE_UNAVAILABLE.
+     */
+    TALER_EC_TRACK_TRANSACTION_EXCHANGE_TIMEOUT = 2300,
+  
+    /**
+     * The backend could not find the merchant instance specified
+     * in the request.   This response is
+     * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+     */
+    TALER_EC_TRACK_TRANSACTION_INSTANCE_UNKNOWN = 2301,
+  
+    /**
+     * The backend could not find the transaction specified
+     * in the request.   This response is
+     * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+     */
+    TALER_EC_TRACK_TRANSACTION_TRANSACTION_UNKNOWN = 2302,
+  
+    /**
+     * The backend had a database access error trying to
+     * retrieve transaction data from its database.
+     * The response is
+     * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TRACK_TRANSACTION_DB_FETCH_TRANSACTION_ERROR = 2303,
+  
+    /**
+     * The backend had a database access error trying to
+     * retrieve payment data from its database.
+     * The response is
+     * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TRACK_TRANSACTION_DB_FETCH_PAYMENT_ERROR = 2304,
+  
+    /**
+     * The backend found no applicable deposits in the database.
+     * This is odd, as we know about the transaction, but not
+     * about deposits we made for the transaction.  The response is
+     * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+     */
+    TALER_EC_TRACK_TRANSACTION_DB_NO_DEPOSITS_ERROR = 2305,
+  
+    /**
+     * We failed to obtain a wire transfer identifier for one
+     * of the coins in the transaction.  The response is
+     * provided with HTTP status code MHD_HTTP_FAILED_DEPENDENCY if
+     * the exchange had a hard error, or MHD_HTTP_ACCEPTED if the
+     * exchange signaled that the transfer was in progress.
+     */
+    TALER_EC_TRACK_TRANSACTION_COIN_TRACE_ERROR = 2306,
+  
+    /**
+     * We failed to obtain the full wire transfer identifier for the
+     * transfer one of the coins was aggregated into.
+     * The response is
+     * provided with HTTP status code MHD_HTTP_FAILED_DEPENDENCY.
+     */
+    TALER_EC_TRACK_TRANSACTION_WIRE_TRANSFER_TRACE_ERROR = 2307,
+  
+    /**
+     * We got conflicting reports from the exhange with
+     * respect to which transfers are included in which
+     * aggregate.
+     * The response is
+     * provided with HTTP status code MHD_HTTP_FAILED_DEPENDENCY.
+     */
+    TALER_EC_TRACK_TRANSACTION_CONFLICTING_REPORTS = 2308,
+  
+  
+    /**
+     * We failed to contact the exchange for the /track/transfer
+     * request.  This response is provided with HTTP status code
+     * MHD_HTTP_SERVICE_UNAVAILABLE.
+     */
+    TALER_EC_TRACK_TRANSFER_EXCHANGE_TIMEOUT = 2400,
+  
+    /**
+     * The backend could not find the merchant instance specified
+     * in the request.   This response is
+     * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+     */
+    TALER_EC_TRACK_TRANSFER_INSTANCE_UNKNOWN = 2401,
+  
+    /**
+     * We failed to persist coin wire transfer information in
+     * our merchant database.
+     * The response is
+     * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TRACK_TRANSFER_DB_STORE_COIN_ERROR = 2402,
+  
+    /**
+     * We internally failed to execute the /track/transfer request.
+     * The response is
+     * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TRACK_TRANSFER_REQUEST_ERROR = 2403,
+  
+    /**
+     * We failed to persist wire transfer information in
+     * our merchant database.
+     * The response is
+     * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TRACK_TRANSFER_DB_STORE_TRANSFER_ERROR = 2404,
+  
+    /**
+     * The exchange returned an error from /track/transfer.
+     * The response is
+     * provided with HTTP status code MHD_HTTP_FAILED_DEPENDENCY.
+     */
+    TALER_EC_TRACK_TRANSFER_EXCHANGE_ERROR = 2405,
+  
+    /**
+     * We failed to fetch deposit information from
+     * our merchant database.
+     * The response is
+     * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TRACK_TRANSFER_DB_FETCH_DEPOSIT_ERROR = 2406,
+  
+    /**
+     * We encountered an internal logic error.
+     * The response is
+     * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TRACK_TRANSFER_DB_INTERNAL_LOGIC_ERROR = 2407,
+  
+    /**
+     * The exchange gave conflicting information about a coin which has
+     * been wire transferred.
+     * The response is provided with HTTP status code 
MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TRACK_TRANSFER_CONFLICTING_REPORTS = 2408,
+  
+    /**
+     * The hash provided in the request of /map/in does not match
+     * the contract sent alongside in the same request.
+     */
+    TALER_EC_MAP_IN_UNMATCHED_HASH = 2500,
+  
+    /**
+     * The backend encountered an error while trying to store the
+     * pair <contract, h_proposal_data> into the database. 
+     * The response is provided with HTTP status code 
MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_MAP_IN_STORE_DB_ERROR = 2501,
+  
+    /**
+     * The backend encountered an error while trying to retrieve the
+     * contract from database.  Likely to be an internal error.
+     */
+    TALER_EC_MAP_OUT_GET_FROM_DB_ERROR = 2502,
+  
+  
+    /**
+     * The backend encountered an error while trying to retrieve the
+     * contract from database.  Likely to be an internal error.
+     */
+    TALER_EC_MAP_OUT_CONTRACT_UNKNOWN = 2503,
+  
+    /* ********** /test API error codes ************* */
+  
+    /**
+     * The exchange failed to compute ECDH.  This response is provided
+     * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TEST_ECDH_ERROR = 4000,
+  
+    /**
+     * The EdDSA test signature is invalid.  This response is provided
+     * with HTTP status code MHD_HTTP_BAD_REQUEST.
+     */
+    TALER_EC_TEST_EDDSA_INVALID = 4001,
+  
+    /**
+     * The exchange failed to compute the EdDSA test signature.  This response 
is provided
+     * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TEST_EDDSA_ERROR = 4002,
+  
+    /**
+     * The exchange failed to generate an RSA key.  This response is provided
+     * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TEST_RSA_GEN_ERROR = 4003,
+  
+    /**
+     * The exchange failed to compute the public RSA key.  This response
+     * is provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TEST_RSA_PUB_ERROR = 4004,
+  
+    /**
+     * The exchange failed to compute the RSA signature.  This response
+     * is provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+     */
+    TALER_EC_TEST_RSA_SIGN_ERROR = 4005,
+  
+  
+    /**
+     * End of error code range.
+     */
+    TALER_EC_END = 9999
+  };
diff --git a/src/api/api-exchange.rst b/src/api/api-exchange.rst
new file mode 100644
index 0000000..1d03dae
--- /dev/null
+++ b/src/api/api-exchange.rst
@@ -0,0 +1,1546 @@
+..
+  This file is part of GNU TALER.
+  Copyright (C) 2014-2018 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU General Public License as published by the Free Software
+  Foundation; either version 2.1, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
details.
+
+  You should have received a copy of the GNU Lesser General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+
+  @author Christian Grothoff
+
+=============================
+The Exchange RESTful JSON API
+=============================
+
+The API specified here follows the :ref:`general conventions <http-common>`
+for all details not specified in the individual requests.
+The `glossary <https://docs.taler.net/glossary.html#glossary>`
+defines all specific terms used in this section.
+
+.. _keys:
+
+-----------------------
+Obtaining Exchange Keys
+-----------------------
+
+This API is used by wallets and merchants to obtain global information about
+the exchange, such as online signing keys, available denominations and the fee
+structure.  This is typically the first call any exchange client makes, as it
+returns information required to process all of the other interactions with the
+exchange.  The returned information is secured by (1) signature(s) from the 
exchange,
+especially the long-term offline signing key of the exchange, which clients 
should
+cache; (2) signature(s) from auditors, and the auditor keys should be
+hard-coded into the wallet as they are the trust anchors for Taler; (3)
+possibly by using HTTPS.
+
+
+.. http:get:: /keys
+
+  Get a list of all denomination keys offered by the bank,
+  as well as the bank's current online signing key.
+
+  **Request:**
+
+  :query last_issue_date: optional argument specifying the maximum value of 
any of the "stamp_start" members of the denomination keys of a "/keys" response 
that is already known to the client. Allows the exchange to only return keys 
that have changed since that timestamp.  The given value must be an unsigned 
64-bit integer representing seconds after 1970.  If the timestamp does not 
exactly match the "stamp_start" of one of the denomination keys, all keys are 
returned.
+
+  **Response:**
+
+  :status 200 OK:
+    The exchange responds with a `ExchangeKeysResponse`_ object. This request 
should
+    virtually always be successful.
+
+  **Details:**
+
+  .. _ExchangeKeysResponse:
+  .. code-block:: tsref
+
+    interface ExchangeKeysResponse {
+      // libtool-style representation of the Taler protocol version, see
+      // 
https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
+      // The format is "current:revision:age".
+      version: String;
+
+      // EdDSA master public key of the exchange, used to sign entries in 
`denoms` and `signkeys`
+      master_public_key: EddsaPublicKey;
+
+      // Relative duration until inactive reserves are closed; not signed, 
expressed as
+      // a string in relative time in microseconds, i.e. "/Delay(1000)/" for 1 
second.
+      reserve_closing_delay: RelativeTime;
+
+      // Denominations offered by this exchange.
+      denoms: Denom[];
+
+      // Denominations for which the exchange currently offers/requests 
payback.
+      payback: Payback[];
+
+      // The date when the denomination keys were last updated.
+      list_issue_date: Timestamp;
+
+      // Auditors of the exchange.
+      auditors: Auditor[];
+
+      // The exchange's signing keys.
+      signkeys: SignKey[];
+
+      // compact EdDSA `signature`_ (binary-only) over the SHA-512 hash of the
+      // concatenation of all SHA-512 hashes of the RSA denomination public 
keys
+      // in `denoms` in the same order as they were in `denoms`.  Note that for
+      // hashing, the binary format of the RSA public keys is used, and not 
their
+      // `base32 encoding <base32>`_.  Wallets cannot do much with this 
signature by itself;
+      // it is only useful when multiple clients need to establish that the 
exchange
+      // is sabotaging end-user anonymity by giving disjoint denomination keys 
to
+      // different users.  If a exchange were to do this, this signature 
allows the
+      // clients to demonstrate to the public that the exchange is dishonest.
+      eddsa_sig: EddsaSignature;
+
+      // Public EdDSA key of the exchange that was used to generate the 
signature.
+      // Should match one of the exchange's signing keys from /keys.  It is 
given
+      // explicitly as the client might otherwise be confused by clock skew as 
to
+      // which signing key was used.
+      eddsa_pub: EddsaPublicKey;
+    }
+
+  .. _tsref-type-Denom:
+  .. code-block:: tsref
+
+    interface Denom {
+      // How much are coins of this denomination worth?
+      value: Amount;
+
+      // When does the denomination key become valid?
+      stamp_start: Timestamp;
+
+      // When is it no longer possible to deposit coins
+      // of this denomination?
+      stamp_expire_withdraw: Timestamp;
+
+      // Timestamp indicating by when legal disputes relating to these coins 
must
+      // be settled, as the exchange will afterwards destroy its evidence 
relating to
+      // transactions involving this coin.
+      stamp_expire_legal: Timestamp;
+
+      // Public (RSA) key for the denomination.
+      denom_pub: RsaPublicKey;
+
+      // Fee charged by the exchange for withdrawing a coin of this 
denomination
+      fee_withdraw: Amount;
+
+      // Fee charged by the exchange for depositing a coin of this denomination
+      fee_deposit: Amount;
+
+      // Fee charged by the exchange for refreshing a coin of this denomination
+      fee_refresh: Amount;
+
+      // Fee charged by the exchange for refunding a coin of this denomination
+      fee_refund: Amount;
+
+      // Signature of `TALER_DenominationKeyValidityPS`_
+      master_sig: EddsaSignature;
+    }
+
+  Fees for any of the operations can be zero, but the fields must still be
+  present. The currency of the `fee_deposit`, `fee_refresh` and `fee_refund` 
must match the
+  currency of the `value`.  Theoretically, the `fee_withdraw` could be in a
+  different currency, but this is not currently supported by the
+  implementation.
+
+  .. _tsref-type-Payback:
+  .. code-block:: tsref
+
+    interface Payback {
+      // hash of the public key of the denomination that is being revoked under
+      // emergency protocol (see /payback).
+      h_denom_pub: HashCode;
+
+      // We do not include any signature here, as the primary use-case for
+      // this emergency involves the exchange having lost its signing keys,
+      // so such a signature here would be pretty worthless.  However, the
+      // exchange will not honor /payback requests unless they are for
+      // denomination keys listed here.
+    }
+
+  A signing key in the `signkeys` list is a JSON object with the following 
fields:
+
+  .. _tsref-type-SignKey:
+  .. code-block:: tsref
+
+    interface SignKey {
+      // The actual exchange's EdDSA signing public key.
+      key: EddsaPublicKey;
+
+      // Initial validity date for the signing key.
+      stamp_start: Timestamp;
+
+      // Date when the exchange will stop using the signing key, allowed to 
overlap
+      // slightly with the next signing key's validity to allow for clock skew.
+      stamp_expire: Timestamp;
+
+      // Date when all signatures made by the signing key expire and should
+      // henceforth no longer be considered valid in legal disputes.
+      stamp_end: Timestamp;
+
+      // Signature over `key` and `stamp_expire` by the exchange master key.
+      // Must have purpose TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY.
+      master_sig: EddsaSignature;
+    }
+
+  An entry in the `auditors` list is a JSON object with the following fields:
+
+  .. _tsref-type-Auditor:
+  .. code-block:: tsref
+
+    interface Auditor {
+      // The auditor's EdDSA signing public key.
+      auditor_pub: EddsaPublicKey;
+
+      // The auditor's URL.
+      auditor_url: string;
+
+      // An array of denomination keys the auditor affirms with its signature.
+      // Note that the message only includes the hash of the public key, while 
the
+      // signature is actually over the expanded information including 
expiration
+      // times and fees.  The exact format is described below.
+      denomination_keys: DenominationKey[];
+    }
+
+  .. _tsref-type-DenominationKey:
+  .. code-block:: tsref
+
+    interface DenominationKey {
+      // hash of the public RSA key used to sign coins of the respective
+      // denomination.  Note that the auditor's signature covers more than just
+      // the hash, but this other information is already provided in `denoms` 
and
+      // thus not repeated here.
+      denom_pub_h: HashCode;
+
+      // Signature of `TALER_ExchangeKeyValidityPS`_
+      auditor_sig: EddsaSignature;
+    }
+
+  The same auditor may appear multiple times in the array for different subsets
+  of denomination keys, and the same denomination key hash may be listed
+  multiple times for the same or different auditors.  The wallet or merchant
+  just should check that the denomination keys they use are in the set for at
+  least one of the auditors that they accept.
+
+  .. note::
+
+    Both the individual denominations *and* the denomination list is signed,
+    allowing customers to prove that they received an inconsistent list.
+
+.. _wire-req:
+
+-----------------------------------
+Obtaining wire-transfer information
+-----------------------------------
+
+.. http:get:: /wire
+
+  Returns a list of payment methods supported by the exchange.  The idea is 
that wallets may use this information to instruct users on how to perform wire 
transfers to top up their wallets.
+
+  **Response:**
+
+  :status 200: The exchange responds with a `WireResponse`_ object. This 
request should virtually always be successful.
+
+  **Details:**
+
+  .. _WireResponse:
+  .. _tsref-type-WireResponse:
+  .. code-block:: tsref
+
+    interface WireResponse {
+
+      // Array of wire accounts operated by the exchange for
+      // incoming wire transfers.
+      accounts: WireAccount[];
+
+      // Object mapping names of wire methods (i.e. "sepa" or "x-taler-bank")
+      // to wire fees.
+      fees: { method : AggregateTransferFee };
+    }
+
+  The specification for the account object is:
+
+  .. _WireAccouunt:
+  .. _tsref-type-WireAccount:
+  .. code-block:: tsref
+
+    interface WireAccount {
+      // payto:// URL identifying the account and wire method
+      url: string;
+
+      // Salt value (used when hashing 'url' to verify signature)
+      salt: string;
+
+      // Signature using the exchange's offline key
+      // with purpose TALER_SIGNATURE_MASTER_WIRE_DETAILS.
+      master_sig: EddsaSignature;
+    }
+
+  Aggregate wire transfer fees representing the fees the exchange
+  charges per wire transfer to a merchant must be specified as an
+  array in all wire transfer response objects under `fees`.  The
+  respective array contains objects with the following members:
+
+  .. _AggregateTransferFee:
+  .. _tsref-type-AggregateTransferFee:
+  .. code-block:: tsref
+
+    interface AggregateTransferFee {
+      // Per transfer wire transfer fee.
+      wire_fee: Amount;
+
+      // Per transfer closing fee.
+      closing_fee: Amount;
+
+      // What date (inclusive) does this fee go into effect?
+      // The different fees must cover the full time period in which
+      // any of the denomination keys are valid without overlap.
+      start_date: Timestamp;
+
+      // What date (exclusive) does this fee stop going into effect?
+      // The different fees must cover the full time period in which
+      // any of the denomination keys are valid without overlap.
+      end_date: Timestamp;
+
+      // Signature of `TALER_MasterWireFeePS`_ with purpose 
TALER_SIGNATURE_MASTER_WIRE_FEES
+      sig: EddsaSignature;
+    }
+
+----------
+Withdrawal
+----------
+
+This API is used by the wallet to obtain digital coins.
+
+When transfering money to the exchange such as via SEPA transfers, the 
exchange creates
+a *reserve*, which keeps the money from the customer.  The customer must
+specify an EdDSA reserve public key as part of the transfer, and can then
+withdraw digital coins using the corresponding private key.  All incoming and
+outgoing transactions are recorded under the corresponding public key by the
+exchange.
+
+  .. note::
+
+     Eventually the exchange will need to advertise a policy for how long it 
will keep transaction histories for inactive or even fully drained reserves.  
We will therefore need some additional handler similar to `/keys` to advertise 
those terms of service.
+
+
+.. http:get:: /reserve/status
+
+  Request information about a reserve.
+
+  .. note::
+    The client currently does not have to demonstrate knowledge of the private
+    key of the reserve to make this request, which makes the reserve's public
+    key privileged information known only to the client, their bank, and the
+    exchange.  In future, we might wish to revisit this decision to improve
+    security, such as by having the client EdDSA-sign an ECDHE key to be used
+    to derive a symmetric key to encrypt the response.  This would be useful if
+    for example HTTPS were not used for communication with the exchange.
+
+  **Request:**
+
+  :query reserve_pub: EdDSA reserve public key identifying the reserve.
+
+  **Response:**
+
+  :status 200 OK:
+    The exchange responds with a `ReserveStatus`_ object;  the reserve was 
known to the exchange,
+  :status 404 Not Found: The reserve key does not belong to a reserve known to 
the exchange.
+
+  **Details:**
+
+  .. _ReserveStatus:
+  .. code-block:: tsref
+
+    interface ReserveStatus {
+      // Balance left in the reserve.
+      balance: Amount;
+
+      // Transaction history for this reserve
+      history: TransactionHistoryItem[];
+    }
+
+  Objects in the transaction history have the following format:
+
+  .. _tsref-type-TransactionHistoryItem:
+  .. code-block:: tsref
+
+    interface TransactionHistoryItem {
+      // Either "WITHDRAW", "DEPOSIT", "PAYBACK", or "CLOSING"
+      type: string;
+
+      // The amount that was withdrawn or deposited (incl. fee)
+      // or paid back, or the closing amount.
+      amount: Amount;
+
+      // Hash of the denomination public key of the coin, if
+      // type is "WITHDRAW".
+      h_denom_pub?: base32;
+
+      // Hash of the blinded coin to be signed, if
+      // type is "WITHDRAW".
+      h_coin_envelope?: base32;
+
+      // Signature of `TALER_WithdrawRequestPS`_ created with the `reserves's 
private key <reserve-priv>`_.  Only present if type is "WITHDRAW".
+      reserve_sig?: EddsaSignature;
+
+      // The fee that was charged for "WITHDRAW".
+      withdraw_fee?: Amount;
+
+      // The fee that was charged for "CLOSING".
+      closing_fee?: Amount;
+
+      // Sender account payto://-URL, only present if type is "DEPOSIT".
+      sender_account_url?: String;
+
+      // Receiver account details, only present if type is "PAYBACK".
+      receiver_account_details?: any;
+
+      // Wire transfer identifier, only present if type is "PAYBACK".
+      wire_transfer?: any;
+
+      // Transfer details uniquely identifying the transfer, only present if 
type is "DEPOSIT".
+      wire_reference?: any;
+
+      // Wire transfer subject, only present if type is "CLOSING".
+      wtid?: any;
+
+      // Hash of the wire account into which the funds were
+      // returned to, present if type is "CLOSING".
+      h_wire?: base32;
+
+      // If `type` is "PAYBACK", this is a signature over a `struct 
TALER_PaybackConfirmationPS` with purpose 
TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK.
+      // If `type` is "CLOSING", this is a signature over a `struct 
TALER_ReserveCloseConfirmationPS` with purpose 
TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED.
+      // Not present for other values of `type`.
+      exchange_sig?: EddsaSignature;
+
+      // Public key used to create `exchange_sig`, only present if 
`exchange_sig` is present.
+      exchange_pub?: EddsaPublicKey;
+
+      // Public key of the coin that was paid back; only present if type is 
"PAYBACK".
+      coin_pub?: CoinPublicKey;
+
+      // Timestamp when the exchange received the /payback or executed the 
wire transfer. Only present if `type` is "DEPOSIT", "PAYBACK" or "CLOSING".
+      timestamp?: Timestamp;
+   }
+
+
+.. http:post:: /reserve/withdraw
+
+  Withdraw a coin of the specified denomination.  Note that the client should
+  commit all of the request details, including the private key of the coin and
+  the blinding factor, to disk *before* issuing this request, so that it can
+  recover the information if necessary in case of transient failures, like
+  power outage, network outage, etc.
+
+  **Request:** The request body must be a `WithdrawRequest`_ object.
+
+  **Response:**
+
+  :status 200 OK:
+    The request was succesful, and the response is a `WithdrawResponse`.  Note 
that repeating exactly the same request
+    will again yield the same response, so if the network goes down during the
+    transaction or before the client can commit the coin signature to disk, the
+    coin is not lost.
+  :status 401 Unauthorized: The signature is invalid.
+  :status 404 Not Found:
+    The denomination key or the reserve are not known to the exchange.  If the
+    denomination key is unknown, this suggests a bug in the wallet as the
+    wallet should have used current denomination keys from `/keys`.  If the
+    reserve is unknown, the wallet should not report a hard error yet, but
+    instead simply wait for up to a day, as the wire transaction might simply
+    not yet have completed and might be known to the exchange in the near 
future.
+    In this case, the wallet should repeat the exact same request later again
+    using exactly the same blinded coin.
+  :status 403 Forbidden:
+    The balance of the reserve is not sufficient to withdraw a coin of the 
indicated denomination.
+    The response is `WithdrawError`_ object.
+
+
+  **Details:**
+
+  .. _WithdrawRequest:
+  .. code-block:: tsref
+
+    interface WithdrawRequest {
+      // Hash of a denomination public key (RSA), specifying the type of coin 
the client
+      // would like the exchange to create.
+      denom_pub_hash: HashCode;
+
+      // coin's blinded public key, should be (blindly) signed by the 
exchange's
+      // denomination private key
+      coin_ev: CoinEnvelope;
+
+      // `public (EdDSA) key <reserve-pub>`_ of the reserve from which the 
coin should be
+      // withdrawn.  The total amount deducted will be the coin's value plus 
the
+      // withdrawal fee as specified with the denomination information.
+      reserve_pub: EddsaPublicKey;
+
+      // Signature of `TALER_WithdrawRequestPS`_ created with the `reserves's 
private key <reserve-priv>`_
+      reserve_sig: EddsaSignature;
+    }
+
+
+  .. _WithdrawResponse:
+  .. code-block:: tsref
+
+    interface WithdrawResponse {
+      // The blinded RSA signature over the `coin_ev`, affirms the coin's
+      // validity after unblinding.
+      ev_sig: BlindedRsaSignature;
+    }
+
+  .. _WithdrawError:
+  .. code-block:: tsref
+
+    interface WithdrawError {
+      // Constant "Insufficient funds"
+      error: string;
+
+      // Amount left in the reserve
+      balance: Amount;
+
+      // History of the reserve's activity, in the same format as returned by 
/reserve/status.
+      history: TransactionHistoryItem[]
+    }
+
+.. _deposit-par:
+
+-------
+Deposit
+-------
+
+Deposit operations are requested by a merchant during a transaction. For the
+deposit operation, the merchant has to obtain the deposit permission for a coin
+from their customer who owns the coin.  When depositing a coin, the merchant is
+credited an amount specified in the deposit permission, possibly a fraction of
+the total coin's value, minus the deposit fee as specified by the coin's
+denomination.
+
+
+.. _deposit:
+
+.. http:POST:: /deposit
+
+  Deposit the given coin and ask the exchange to transfer the given 
:ref:`amount`
+  to the merchants bank account.  This API is used by the merchant to redeem
+  the digital coins.  The request should contain a JSON object with the
+  following fields:
+
+  **Request:** The request body must be a `DepositRequest`_ object.
+
+  **Response:**
+
+  :status 200 Ok:
+    The operation succeeded, the exchange confirms that no double-spending 
took place.  The response will include a `DepositSuccess`_ object.
+  :status 401 Unauthorized:
+    One of the signatures is invalid.
+  :status 403 Forbidden:
+    The deposit operation has failed because the coin has insufficient
+    residual value; the request should not be repeated again with this coin.
+    In this case, the response is a `DepositDoubleSpendError`_.
+  :status 404 Not Found:
+    Either the denomination key is not recognized (expired or invalid) or
+    the wire type is not recognized.
+
+  **Details:**
+
+  .. _DepositRequest:
+  .. code-block:: tsref
+
+    interface DepositRequest {
+      // Amount to be deposited, can be a fraction of the
+      // coin's total value.
+      f: Amount;
+
+      // The merchant's account details. This must be a JSON object whose 
format
+      // must correspond to one of the supported wire transfer formats of the 
exchange.
+      // See `wireformats`_.
+      wire: Object;
+
+      // SHA-512 hash of the merchant's payment details from `wire`.  Although
+      // strictly speaking redundant, this helps detect inconsistencies.
+      // TODO: change to 'h_wire'.
+      H_wire: HashCode;
+
+      // SHA-512 hash of the contact of the merchant with the customer.  
Further
+      // details are never disclosed to the exchange.
+      h_contract_terms: HashCode;
+
+      // `coin's public key <eddsa-coin-pub>`_, both ECDHE and EdDSA.
+      coin_pub: CoinPublicKey;
+
+      // Hash of denomination RSA key with which the coin is signed
+      denom_pub_hash: HashCode;
+
+      // exchange's unblinded RSA signature of the coin
+      ub_sig: RsaSignature;
+
+      // timestamp when the contract was finalized, must match approximately 
the
+      // current time of the exchange; if the timestamp is too far off, the
+      // exchange returns "400 Bad Request" with an error code of
+      // "TALER_EC_DEPOSIT_INVALID_TIMESTAMP".
+      timestamp: Timestamp;
+
+      // indicative time by which the exchange undertakes to transfer the 
funds to
+      // the merchant, in case of successful payment.
+      wire_deadline: Timestamp;
+
+      // EdDSA `public key of the merchant <merchant-pub>`_, so that the 
client can identify the
+      // merchant for refund requests.
+      merchant_pub: EddsaPublicKey;
+
+      // date until which the merchant can issue a refund to the customer via 
the
+      // exchange, possibly zero if refunds are not allowed.
+      refund_deadline: Timestamp;
+
+      // Signature of `TALER_DepositRequestPS`_, made by the customer with the 
`coin's private key <coin-priv>`_
+      coin_sig: EddsaSignature;
+    }
+
+  The deposit operation succeeds if the coin is valid for making a deposit and
+  has enough residual value that has not already been deposited or melted.
+
+
+  .. _`tsref-type-DepositSuccess`:
+  .. _DepositSuccess:
+  .. code-block:: tsref
+
+     interface DepositSuccess {
+      // The string constant "DEPOSIT_OK"
+      status: string;
+
+      // the EdDSA signature of `TALER_DepositConfirmationPS`_ using a current
+      // `signing key of the exchange <sign-key-priv>`_ affirming the 
successful
+      // deposit and that the exchange will transfer the funds after the refund
+      // deadline, or as soon as possible if the refund deadline is zero.
+      sig: EddsaSignature;
+
+      // `public EdDSA key of the exchange <sign-key-pub>`_ that was used to
+      // generate the signature.
+      // Should match one of the exchange's signing keys from /keys.  It is 
given
+      // explicitly as the client might otherwise be confused by clock skew as 
to
+      // which signing key was used.
+      pub: EddsaPublicKey;
+    }
+
+  .. _DepositDoubleSpendError:
+  .. code-block:: tsref
+
+    interface DepositDoubleSpendError {
+      // The string constant "insufficient funds"
+      error: string;
+
+      // Transaction history for the coin that is
+      // being double-spended
+      history: CoinSpendHistoryItem[];
+    }
+
+  .. _`tsref-type-CoinSpendHistoryItem`:
+  .. _CoinSpendHistoryItem:
+  .. code-block:: tsref
+
+    interface CoinSpendHistoryItem {
+      // Either "DEPOSIT", "MELT", "REFUND", "PAYBACK",
+      // "OLD-COIN-PAYBACK" or "PAYBACK-REFRESH"
+      type: string;
+
+      // The total amount of the coin's value absorbed (or restored in the 
case of a refund) by this transaction.
+      // Note that for deposit and melt this means the amount given includes
+      // the transaction fee, while for refunds the amount given excludes
+      // the transaction fee. The current coin value can thus be computed by
+      // subtracting deposit and melt amounts and adding refund amounts from
+      // the coin's denomination value.
+      amount: Amount;
+
+      // Deposit fee in case of type "DEPOSIT".
+      deposit_fee: Amount;
+
+      // public key of the merchant, for "DEPOSIT" operations.
+      merchant_pub?: EddsaPublicKey;
+
+      // date when the operation was made.
+      // Only for "DEPOSIT", "PAYBACK", "OLD-COIN-PAYBACK" and
+      // "PAYBACK-REFRESH" operations.
+      timestamp?: Timestamp;
+
+      // date until which the merchant can issue a refund to the customer via 
the
+      // exchange, possibly zero if refunds are not allowed. Only for 
"DEPOSIT" operations.
+      refund_deadline?: Timestamp;
+
+      // Signature by the coin, only present if `type` is "DEPOSIT" or "MELT"
+      coin_sig?: EddsaSignature;
+
+      // Deposit fee in case of type "MELT".
+      melt_fee: Amount;
+
+      // Commitment from the melt operation, only for "MELT".
+      rc?: TALER_RefreshCommitmentP;
+
+      // Hash of the bank account from where we received the funds,
+      // only present if `type` is "DEPOSIT"
+      h_wire?: HashCode;
+
+      // Deposit fee in case of type "REFUND".
+      refund_fee?: Amount;
+
+      // Hash over the proposal data of the contract that
+      // is being paid (if type is "DEPOSIT") or refunded (if
+      // `type` is "REFUND"); otherwise absent.
+      h_contract_terms?: HashCode;
+
+      // Refund transaction ID.  Only present if `type` is
+      // "REFUND"
+      rtransaction_id?: integer;
+
+      // `EdDSA Signature <eddsa-sig>`_ authorizing the REFUND. Made with
+      // the `public key of the merchant <merchant-pub>`_.
+      // Only present if `type` is "REFUND"
+      merchant_sig?: EddsaSignature;
+
+      // public key of the reserve that will receive the funds, for "PAYBACK" 
operations.
+      reserve_pub?: EddsaPublicKey;
+
+      // Signature by the exchange, only present if `type` is "PAYBACK",
+      // "OLD-COIN-PAYBACK" or "PAYBACK-REFRESH".  Signature is
+      // of type TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK for "PAYBACK",
+      // and of type TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK_REFRESH 
otherwise.
+      exchange_sig?: EddsaSignature;
+
+      // public key used to sign `exchange_sig`, only present if 
`exchange_sig` present.
+      exchange_pub?: EddsaPublicKey;
+
+      // Blinding factor of the revoked new coin,
+      // only present if `type` is "REFRESH_PAYBACK".
+      new_coin_blinding_secret: RsaBlindingKeySecret;
+
+      // Blinded public key of the revoked new coin,
+      // only present if `type` is "REFRESH_PAYBACK".
+      new_coin_ev: RsaBlindingKeySecret;
+    }
+
+----------
+Refreshing
+----------
+
+Refreshing creates `n` new coins from `m` old coins, where the sum of
+denominations of the new coins must be smaller than the sum of the old coins'
+denominations plus melting (refresh) and withdrawal fees charged by the 
exchange.
+The refreshing API can be used by wallets to melt partially spent coins, making
+transactions with the freshly exchangeed coins unlinkabe to previous 
transactions
+by anyone except the wallet itself.
+
+However, the new coins are linkable from the private keys of all old coins
+using the /refresh/link request.  While /refresh/link must be implemented by
+the exchange to achieve taxability, wallets do not really ever need that part 
of
+the API during normal operation.
+
+.. _refresh:
+.. http:post:: /refresh/melt
+
+  "Melts" coins.  Invalidates the coins and prepares for exchangeing of fresh
+  coins.  Taler uses a global parameter `kappa` for the cut-and-choose
+  component of the protocol, for which this request is the commitment.  Thus,
+  various arguments are given `kappa`-times in this step.  At present `kappa`
+  is always 3.
+
+
+  :status 401 Unauthorized:
+    One of the signatures is invalid.
+  :status 200 OK:
+    The request was succesful.  The response body is `MeltResponse`_ in this 
case.
+  :status 403 Forbidden:
+    The operation is not allowed as at least one of the coins has insufficient 
funds.  The response
+    is `MeltForbiddenResponse`_ in this case.
+  :status 404:
+    the exchange does not recognize the denomination key as belonging to the 
exchange,
+    or it has expired
+
+  **Details:**
+
+
+  .. code-block:: tsref
+
+    interface MeltRequest {
+
+      // `Coin public key <eddsa-coin-pub>`_, uniquely identifies the coin to 
be melted
+      coin_pub: string;
+
+      // Hash of the denomination public key, to determine total coin value.
+      denom_pub_hash: HashCode;
+
+      // Signature over the `coin public key <eddsa-coin-pub>`_ by the 
denomination.
+      denom_sig: RsaSignature;
+
+      // Signature by the `coin <coin-priv>`_ over the melt commitment.
+      confirm_sig: EddsaSignature;
+
+      // Amount of the value of the coin that should be melted as part of
+      // this refresh operation, including melting fee.
+      value_with_fee: Amount;
+
+      // Melt commitment.  Hash over the various coins to be withdrawn.
+      // See also `TALER_refresh_get_commitment()`
+      rc: TALER_RefreshCommitmentP;
+
+    }
+
+  For details about the HKDF used to derive the new coin private keys and
+  the blinding factors from ECDHE between the transfer public keys and
+  the private key of the melted coin, please refer to the
+  implementation in `libtalerutil`.
+
+  .. _tsref-type-MeltResponse:
+  .. _MeltResponse:
+  .. code-block:: tsref
+
+    interface MeltResponse {
+      // Which of the `kappa` indices does the client not have to reveal.
+      noreveal_index: number;
+
+      // Signature of `TALER_RefreshMeltConfirmationPS`_ whereby the exchange
+      // affirms the successful melt and confirming the `noreveal_index`
+      exchange_sig: EddsaSignature;
+
+      // `public EdDSA key <sign-key-pub>`_ of the exchange that was used to 
generate the signature.
+      // Should match one of the exchange's signing keys from /keys.  Again 
given
+      // explicitly as the client might otherwise be confused by clock skew as 
to
+      // which signing key was used.
+      exchange_pub: EddsaPublicKey;
+    }
+
+
+  .. _tsref-type-MeltForbiddenResponse:
+  .. _MeltForbiddenResponse:
+  .. code-block:: tsref
+
+    interface MeltForbiddenResponse {
+      // Always "insufficient funds"
+      error: string;
+
+      // public key of a melted coin that had insufficient funds
+      coin_pub: EddsaPublicKey;
+
+      // original total value of the coin
+      original_value: Amount;
+
+      // remaining value of the coin
+      residual_value: Amount;
+
+      // amount of the coin's value that was to be melted
+      requested_value: Amount;
+
+      // The transaction list of the respective coin that failed to have 
sufficient funds left.
+      // Note that only the transaction history for one bogus coin is given,
+      // even if multiple coins would have failed the check.
+      history: CoinSpendHistoryItem[];
+    }
+
+
+.. http:post:: /refresh/reveal
+
+  Reveal previously commited values to the exchange, except for the values
+  corresponding to the `noreveal_index` returned by the /exchange/melt step.
+
+  Errors such as failing to do proper arithmetic when it comes to calculating
+  the total of the coin values and fees are simply reported as bad requests.
+  This includes issues such as melting the same coin twice in the same session,
+  which is simply not allowed.  However, theoretically it is possible to melt a
+  coin twice, as long as the `value_with_fee` of the two melting operations is
+  not larger than the total remaining value of the coin before the melting
+  operations. Nevertheless, this is not really useful.
+
+  :status 200 OK:
+    The transfer private keys matched the commitment and the original request 
was well-formed.
+    The response body is a `RevealResponse`_
+  :status 409 Conflict:
+    There is a problem between the original commitment and the revealed private
+    keys.  The returned information is proof of the missmatch, and therefore
+    rather verbose, as it includes most of the original /refresh/melt request,
+    but of course expected to be primarily used for diagnostics.
+    The response body is a `RevealConflictResponse`_.
+
+  **Details:**
+
+  Request body contains a JSON object with the following fields:
+
+  .. code-block:: tsref
+
+    interface RevealRequest {
+
+      // Array of `n` new hash codes of denomination public keys to order.
+      new_denoms_h: HashCode[];
+
+      // Array of `n` entries with blinded coins,
+      // matching the respective entries in `new_denoms`.
+      coin_evs: CoinEnvelope[];
+
+      // `kappa - 1` transfer private keys (ephemeral ECDHE keys)
+      transfer_privs: EddsaPrivateKey[];
+
+      // transfer public key at the `noreveal_index`.
+      transfer_pub: EddsaPublicKey;
+
+      // Array of `n` signatures made by the wallet using the old coin's 
private key,
+      // used later to verify the /refresh/link response from the exchange.
+      // Signs over a `TALER_CoinLinkSignaturePS`_
+      link_sigs: EddsaSignature[];
+
+      // The original commitment, used to match the /refresh/reveal
+      // to the corresponding /refresh/melt operation.
+      rc: HashCode;
+    }
+
+
+  .. _RevealResponse:
+  .. code-block:: tsref
+
+    interface RevealResponse {
+      // List of the exchange's blinded RSA signatures on the new coins.  Each
+      // element in the array is another JSON object which contains the 
signature
+      // in the "ev_sig" field.
+      ev_sigs: BlindedRsaSignature[];
+    }
+
+
+  .. _RevealConflictResponse:
+  .. code-block:: tsref
+
+    interface RevealConflictResponse {
+      // Constant "commitment violation"
+      error: string;
+
+      // Detailed error code
+      code: integer;
+
+      // Commitment as calculated by the exchange from the revealed data.
+      rc_expected: HashCode;
+
+    }
+
+
+.. http:get:: /refresh/link
+
+  Link the old public key of a melted coin to the coin(s) that were exchangeed 
during the refresh operation.
+
+  **Request:**
+
+  :query coin_pub: melted coin's public key
+
+  **Response:**
+
+  :status 200 OK:
+    All commitments were revealed successfully.  The exchange returns an array,
+    typically consisting of only one element, in which each each element 
contains
+    information about a melting session that the coin was used in.
+  :status 404 Not Found:
+    The exchange has no linkage data for the given public key, as the coin has 
not
+    yet been involved in a refresh operation.
+
+  **Details:**
+
+  .. _tsref-type-LinkResponse:
+  .. code-block:: tsref
+
+    interface LinkResponse {
+      // transfer ECDHE public key corresponding to the `coin_pub`, used to
+      // compute the blinding factor and private key of the fresh coins.
+      transfer_pub: EcdhePublicKey;
+
+      // array with (encrypted/blinded) information for each of the coins
+      // exchangeed in the refresh operation.
+      new_coins: NewCoinInfo[];
+    }
+
+  .. _tsref-type-NewCoinInfo:
+  .. code-block:: tsref
+
+    interface NewCoinInfo {
+      // RSA public key of the exchangeed coin.
+      denom_pub: RsaPublicKey;
+
+      // Exchange's blinded signature over the exchangeed coin.
+      ev_sig: BlindedRsaSignature;
+
+      // Blinded coin, to be verified by the wallet to protect against
+      // a malicious exchange.
+      coin_ev: CoinEnvelope;
+
+      // Signature made by the old coin over the refresh request.
+      // Signs over a `TALER_CoinLinkSignaturePS`_
+      link_sig: EddsaSignature;
+    }
+
+
+-------------------
+Emergency Cash-Back
+-------------------
+
+This API is only used if the exchange is either about to go out of
+business or has had its private signing keys compromised (so in
+either case, the protocol is only used in **abnormal**
+situations).  In the above cases, the exchange signals to the
+wallets that the emergency cash back protocol has been activated
+by putting the affected denomination keys into the cash-back
+part of the /keys response.  If and only if this has happened,
+coins that were signed with those denomination keys can be cashed
+in using this API.
+
+   .. note::
+
+      This is a proposed API, we are implementing it as bug #3887.
+
+.. http:post:: /payback
+
+  Demand that a coin be refunded via wire transfer to the original owner.
+
+  **Request:** The request body must be a `PaybackRequest`_ object.
+
+  **Response:**
+  :status 200 OK:
+  The request was succesful, and the response is a `PaybackConfirmation`.
+  Note that repeating exactly the same request
+  will again yield the same response, so if the network goes down during the
+  transaction or before the client can commit the coin signature to disk, the
+  coin is not lost.
+  :status 401 Unauthorized: The coin's signature is invalid.
+  :status 403 Forbidden: The coin was already used for payment.
+  The response is a `DepositDoubleSpendError`_.
+  :status 404 Not Found:
+  The denomination key is not in the set of denomination
+  keys where emergency pay back is enabled, or the blinded
+  coin is not known to have been withdrawn.
+
+  **Details:**
+
+  .. _PaybackRequest:
+  .. code-block:: tsref
+
+    interface PaybackRequest {
+      // Hash of denomination public key (RSA), specifying the type of coin 
the client
+      // would like the exchange to pay back.
+      denom_pub_hash: HashCode;
+
+      // Signature over the `coin public key <eddsa-coin-pub>`_ by the 
denomination.
+      denom_sig: RsaSignature;
+
+      // coin's public key
+      coin_pub: CoinPublicKey;
+
+      // coin's blinding factor
+      coin_blind_key_secret: RsaBlindingKeySecret;
+
+      // Signature of `TALER_PaybackRequestPS`_ created with the `coin's 
private key <coin-priv>`_
+      coin_sig: EddsaSignature;
+
+      // Was the coin refreshed (and thus the payback should go to the old 
coin)?
+      // Optional (for backwards compatibility); if absent, "false" is assumed
+      refreshed?: boolean;
+    }
+
+
+  .. _PaybackConfirmation:
+  .. code-block:: tsref
+
+    interface PaybackConfirmation {
+      // public key of the reserve that will receive the payback,
+      // provided if refreshed was false.
+      reserve_pub?: EddsaPublicKey;
+
+      // public key of the old coin that will receive the payback,
+      // provided if refreshed was true.
+      old_coin_pub?: EddsaPublicKey;
+
+      // How much will the exchange pay back (needed by wallet in
+      // case coin was partially spent and wallet got restored from backup)
+      amount: Amount;
+
+      // Time by which the exchange received the /payback request.
+      timestamp: Timestamp;
+
+      // the EdDSA signature of `TALER_PaybackConfirmationPS`_ (refreshed 
false)
+      // or `TALER_PaybackRefreshConfirmationPS_` (refreshed true) using a 
current
+      // `signing key of the exchange <sign-key-priv>`_ affirming the 
successful
+      // payback request, and that the exchange promises to transfer the funds
+      // by the date specified (this allows the exchange delaying the transfer
+      // a bit to aggregate additional payback requests into a larger one).
+      exchange_sig: EddsaSignature;
+
+      // Public EdDSA key of the exchange that was used to generate the 
signature.
+      // Should match one of the exchange's signing keys from /keys.  It is 
given
+      // explicitly as the client might otherwise be confused by clock skew as 
to
+      // which signing key was used.
+      exchange_pub: EddsaPublicKey;
+    }
+
+
+-----------------------
+Tracking wire transfers
+-----------------------
+
+This API is used by merchants that need to find out which wire
+transfers (from the exchange to the merchant) correspond to which deposit
+operations.  Typically, a merchant will receive a wire transfer with a
+**wire transfer identifier** and want to know the set of deposit
+operations that correspond to this wire transfer.  This is the
+preferred query that merchants should make for each wire transfer they
+receive.  If a merchant needs to investigate a specific deposit
+operation (i.e. because it seems that it was not paid), then the
+merchant can also request the wire transfer identifier for a deposit
+operation.
+
+Sufficient information is returned to verify that the coin signatures
+are correct. This also allows governments to use this API when doing
+a tax audit on merchants.
+
+Naturally, the returned information may be sensitive for the merchant.
+We do not require the merchant to sign the request, as the same requests
+may also be performed by the government auditing a merchant.
+However, wire transfer identifiers should have sufficient entropy to
+ensure that obtaining a successful reply by brute-force is not practical.
+Nevertheless, the merchant should protect the wire transfer identifiers
+from his bank statements against unauthorized access, least his income
+situation is revealed to an adversary. (This is not a major issue, as
+an adversary that has access to the line-items of bank statements can
+typically also view the balance.)
+
+
+.. http:get:: /track/transfer
+
+  Provides deposits associated with a given wire transfer.
+
+  **Request:**
+
+  :query wtid: raw wire transfer identifier identifying the wire transfer (a 
base32-encoded value)
+
+  **Response:**
+
+  :status 200 OK:
+    The wire transfer is known to the exchange, details about it follow in the 
body.
+    The body of the response is a `TrackTransferResponse`_.
+  :status 404 Not Found:
+    The wire transfer identifier is unknown to the exchange.
+
+  .. _TrackTransferResponse:
+  .. _tsref-type-TrackTransferResponse:
+  .. code-block:: tsref
+
+    interface TrackTransferResponse {
+      // Total amount transferred
+      total: Amount;
+
+      // Applicable wire fee that was charged
+      wire_fee: Amount;
+
+      // public key of the merchant (identical for all deposits)
+      merchant_pub: EddsaPublicKey;
+
+      // hash of the wire details (identical for all deposits)
+      H_wire: HashCode;
+
+      // Time of the execution of the wire transfer by the exchange
+      execution_time: Timestamp;
+
+      // details about the deposits
+      deposits: TrackTransferDetail[];
+
+      // signature from the exchange made with purpose
+      // `TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT`
+      exchange_sig: EddsaSignature;
+
+      // public EdDSA key of the exchange that was used to generate the 
signature.
+      // Should match one of the exchange's signing keys from /keys.  Again 
given
+      // explicitly as the client might otherwise be confused by clock skew as 
to
+      // which signing key was used.
+      exchange_pub: EddsaSignature;
+    }
+
+  .. _tsref-type-TrackTransferDetail:
+  .. code-block:: tsref
+
+    interface TrackTransferDetail {
+      // SHA-512 hash of the contact of the merchant with the customer.
+      h_contract_terms: HashCode;
+
+      // coin's public key, both ECDHE and EdDSA.
+      coin_pub: CoinPublicKey;
+
+      // The total amount the original deposit was worth.
+      deposit_value: Amount;
+
+      // applicable fees for the deposit
+      deposit_fee: Amount;
+
+    }
+
+.. http:post:: /track/transaction
+
+  Provide the wire transfer identifier associated with an (existing) deposit 
operation.
+
+  **Request:** The request body must be a `TrackTransactionRequest`_ JSON 
object.
+
+  **Response:**
+
+  :status 200 OK:
+    The deposit has been executed by the exchange and we have a wire transfer 
identifier.
+    The response body is a `TrackTransactionResponse`_ object.
+  :status 202 Accepted:
+    The deposit request has been accepted for processing, but was not yet
+    executed.  Hence the exchange does not yet have a wire transfer 
identifier.  The
+    merchant should come back later and ask again.
+    The response body is a `TrackTransactionAcceptedResponse`_.
+  :status 401 Unauthorized: The signature is invalid.
+  :status 404 Not Found: The deposit operation is unknown to the exchange
+
+  **Details:**
+
+  .. _tsref-type-TrackTransactionRequest:
+  .. _TrackTransactionRequest:
+  .. code-block:: tsref
+
+    interface TrackTransactionRequest {
+      // SHA-512 hash of the merchant's payment details.
+      H_wire: HashCode;
+
+      // SHA-512 hash of the contact of the merchant with the customer.
+      h_contract_terms: HashCode;
+
+      // coin's public key, both ECDHE and EdDSA.
+      coin_pub: CoinPublicKey;
+
+      // the EdDSA public key of the merchant, so that the client can identify
+      // the merchant for refund requests.
+      merchant_pub: EddsaPublicKey;
+
+      // the EdDSA signature of the merchant made with purpose
+      // `TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION` , affirming that it is 
really the
+      // merchant who requires obtaining the wire transfer identifier.
+      merchant_sig: EddsaSignature;
+    }
+
+
+  .. _tsref-type-TrackTransactionResponse:
+  .. _TrackTransactionResponse:
+  .. code-block:: tsref
+
+    interface TrackTransactionResponse {
+      // raw wire transfer identifier of the deposit.
+      wtid: Base32;
+
+      // when was the wire transfer given to the bank.
+      execution_time: Timestamp;
+
+      // The contribution of this coin to the total (without fees)
+      coin_contribution: Amount;
+
+      // Total amount transferred
+      total_amount: Amount;
+
+      // binary-only Signature_ for purpose 
`TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE`
+      // whereby the exchange affirms the successful wire transfer.
+      exchange_sig: EddsaSignature;
+
+      // public EdDSA key of the exchange that was used to generate the 
signature.
+      // Should match one of the exchange's signing keys from /keys.  Again 
given
+      // explicitly as the client might otherwise be confused by clock skew as 
to
+      // which signing key was used.
+      exchange_pub: EddsaPublicKey;
+    }
+
+  .. _tsref-type-TrackTransactionAcceptedResponse:
+  .. _TrackTransactionAcceptedResponse:
+  .. code-block:: tsref
+
+    interface TrackTransactionAcceptedResponse {
+      // time by which the exchange currently thinks the deposit will be 
executed.
+      execution_time: Timestamp;
+    }
+
+
+-------
+Refunds
+-------
+
+.. _refund:
+.. http:POST:: /refund
+
+  Undo deposit of the given coin, restoring its value.
+
+  **Request:** The request body must be a `RefundRequest`_ object.
+
+  **Response:**
+
+  :status 200 Ok:
+    The operation succeeded, the exchange confirms that the coin can now be 
refreshed.  The response will include a `RefundSuccess`_ object.
+  :status 401 Unauthorized:
+    Merchant signature is invalid.
+  :status 404 Not found:
+    The refund operation failed as we could not find a matching deposit 
operation (coin, contract, transaction ID and merchant public key must all 
match).
+  :status 410 Gone:
+    It is too late for a refund by the exchange, the money was already sent to 
the merchant.
+
+  **Details:**
+
+  .. _RefundRequest:
+  .. code-block:: tsref
+
+     interface RefundRequest {
+
+      // Amount to be refunded, can be a fraction of the
+      // coin's total deposit value (including deposit fee);
+      // must be larger than the refund fee.
+      refund_amount: Amount;
+
+      // Refund fee associated with the given coin.
+      // must be smaller than the refund amount.
+      refund_fee: Amount;
+
+      // SHA-512 hash of the contact of the merchant with the customer.
+      h_contract_terms: HashCode;
+
+      // coin's public key, both ECDHE and EdDSA.
+      coin_pub: CoinPublicKey;
+
+      // 64-bit transaction id of the refund transaction between merchant and 
customer
+      rtransaction_id: number;
+
+      // EdDSA public key of the merchant.
+      merchant_pub: EddsaPublicKey;
+
+      // EdDSA signature of the merchant affirming the refund.
+      merchant_sig: EddsaPublicKey;
+
+    }
+
+  .. _RefundSuccess:
+  .. code-block:: tsref
+
+    interface RefundSuccess {
+      // The string constant "REFUND_OK"
+      status: string;
+
+      // the EdDSA :ref:`signature` (binary-only) with purpose
+      // `TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND` using a current signing key 
of the
+      // exchange affirming the successful refund
+      sig: EddsaSignature;
+
+      // public EdDSA key of the exchange that was used to generate the 
signature.
+      // Should match one of the exchange's signing keys from /keys.  It is 
given
+      // explicitly as the client might otherwise be confused by clock skew as 
to
+      // which signing key was used.
+      pub: EddsaPublicKey;
+   }
+
+
+------------
+The Test API
+------------
+
+The test API is not there to test the exchange, but to allow
+clients of the exchange (merchant and wallet implementations)
+to test if their implemenation of the cryptography is
+binary-compatible with the implementation of the exchange.
+
+.. http:POST:: /test/base32
+
+  Test hashing and Crockford :ref:`base32` encoding.
+
+  **Request:**
+
+  .. code-block:: tsref
+
+    {
+      // some base32-encoded value
+      input: Base32;
+    }
+
+  **Response:**
+
+  .. code-block:: tsref
+
+    {
+      // the base32_-encoded hash of the input value
+      output: Base32;
+    }
+
+.. http:POST:: /test/encrypt
+
+  Test symmetric encryption.
+
+  **Request:**
+
+  .. code-block:: tsref
+
+    {
+      // Some `base32`_-encoded value
+      input: Base32;
+
+      // some `base32`_-encoded hash that is used to derive the symmetric key 
and
+      // initialization vector for the encryption using the HKDF with "skey" 
and
+      // "iv" as the salt.
+      key_hash: Base32;
+    }
+
+  **Response:**
+
+
+  .. code-block:: tsref
+
+    {
+      // the encrypted value
+      output: Base32;
+    }
+
+.. http:POST:: /test/hkdf
+
+  Test Hash Key Deriviation Function.
+
+  **Request:**
+
+
+  .. code-block:: tsref
+
+    {
+      // Some `base32`_-encoded value
+      input: Base32;
+    }
+
+  **Response:**
+
+
+  .. code-block:: tsref
+
+    {
+      // the HKDF of the input using "salty" as salt
+      output: Base32;
+    }
+
+.. http:POST:: /test/ecdhe
+
+  Test ECDHE.
+
+  **Request:**
+
+  .. code-block:: tsref
+
+    {
+      ecdhe_pub: EcdhePublicKey;
+      ecdhe_priv: EcdhePrivateKey;
+    }
+
+  **Response:**
+
+  .. code-block:: tsref
+
+    {
+      // ECDH result from the two keys
+      ecdhe_hash: HashCode;
+    }
+
+
+.. http:POST:: /test/eddsa
+
+  Test EdDSA.
+
+  **Request:**
+
+  .. code-block:: tsref
+
+    {
+      eddsa_pub: EddsaPublicKey;
+
+      // EdDSA signature using purpose TALER_SIGNATURE_CLIENT_TEST_EDDSA. Note:
+      // the signed payload must be empty, we sign just the purpose here.
+      eddsa_sig: EddsaSignature;
+    }
+
+  **Response:**
+
+  :status 200: the signature was valid
+  :status 401 Unauthorized: the signature was invalid
+
+  The exchange responds with another valid signature, which gives the
+  client the opportunity to test its signature verification implementation.
+
+  .. code-block:: tsref
+
+    {
+      // Another EdDSA public key
+      eddsa_pub: EddsaPublicKey;
+
+      // EdDSA signature using purpose TALER_SIGNATURE_EXCHANGE_TEST_EDDSA
+      eddsa_sig: EddsaSignature;
+    }
+
+
+.. http:GET:: /test/rsa/get
+
+  Obtain the RSA public key used for signing in /test/rsa/sign.
+
+  **Response:**
+
+  .. code-block:: tsref
+
+    {
+      // The RSA public key the client should use when blinding a value for 
the /test/rsa/sign API.
+      rsa_pub: RsaPublicKey;
+    }
+
+.. http:POST:: /test/rsa/sign
+
+  Test RSA blind signatures.
+
+  **Request:**
+
+  .. code-block:: tsref
+
+    {
+      // Blinded value to sign.
+      blind_ev: BlindedRsaSignature;
+    }
+
+  **Response:**
+
+
+  .. code-block:: tsref
+
+    {
+      // Blind RSA signature over the `blind_ev` using the private key
+      // corresponding to the RSA public key returned by /test/rsa/get.
+      rsa_blind_sig: BlindedRsaSignature;
+    }
+
+.. http:POST:: /test/transfer
+
+  Test Transfer decryption.
+
+  **Request:**
+
+  .. code-block:: tsref
+
+    {
+      // Private transfer key
+      trans_priv: string;
+
+      // `Coin public key <eddsa-coin-pub>`_
+      coin_pub: EddsaPublicKey;
+    }
+
+  **Response:**
+
+  :status 200: the operation succeeded
+
+  .. code-block:: tsref
+
+    {
+      // Decrypted transfer secret
+      secret: string;
+    }
diff --git a/src/api/api-merchant.rst b/src/api/api-merchant.rst
new file mode 100644
index 0000000..0d0302f
--- /dev/null
+++ b/src/api/api-merchant.rst
@@ -0,0 +1,1200 @@
+..
+  This file is part of GNU TALER.
+  Copyright (C) 2014, 2015, 2016, 2017 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU General Public License as published by the Free Software
+  Foundation; either version 2.1, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
details.
+
+  You should have received a copy of the GNU Lesser General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+
+  @author Marcello Stanisci
+  @author Florian Dold
+  @author Christian Grothoff
+
+.. _merchant-api:
+
+====================
+Merchant Backend API
+====================
+
+------------------
+Receiving Payments
+------------------
+
+.. _post-order:
+
+.. http:post:: /order
+
+  Create a new order that a customer can pay for.
+
+  This request is not idempotent unless an `order_id` is explicitly specified.
+
+  .. note::
+
+    This endpoint does not return a URL to redirect your user to confirm the 
payment.
+    In order to get this URL use :http:get:`/check-payment`.  The API is 
structured this way
+    since the payment redirect URL is not unique for every order, there might 
be varying parameters
+    such as the session id.
+
+  **Request:**
+
+  The request must be a `PostOrderRequest`_.
+
+  **Response**
+
+  :status 200 OK:
+    The backend has successfully created the proposal.  The response is a
+    `PostOrderResponse`_.
+
+  .. _PostOrderRequest:
+  .. code-block:: tsref
+
+    interface PostOrderRequest {
+      // The order must at least contain the minimal
+      // order detail, but can override all
+      order: MinimalOrderDetail | ContractTerms;
+    }
+
+  The following fields of the `ContractTerms`_
+
+  .. _MinimalOrderDetail:
+  .. _tsref-type-MinimalOrderDetail:
+  .. code-block:: tsref
+
+    interface MinimalOrderRequest {
+      // Amount to be paid by the customer
+      amount: Amount
+
+      // Short summary of the order
+      summary: string;
+
+      // URL that will show that the order was successful after
+      // it has been paid for.  The wallet will automatically append
+      // the order_id (always) and the session_sig (if applicable).
+      fulfillment_url: string;
+
+      // Merchant instance to use (leave empty to use instance "default")
+      instance?: string;
+    }
+
+  .. _PostOrderResponse:
+  .. code-block:: tsref
+
+    interface PostOrderResponse {
+      // Order ID of the response that was just created
+      order_id: string;
+    }
+
+
+.. http:get:: /check-payment
+
+  Check the payment status of an order.  If the order exists but is not payed 
yet,
+  the response provides a redirect URL.
+  When the user goes to this URL, they will be prompted for payment.
+
+  **Request:**
+
+  :query order_id: order id that should be used for the payment
+  :query contract_url: FIXME-FLORIAN
+  :query instance: *Optional*. Instance used for the payment. Defaults to the 
instance named "default".
+  :query resource_url: *Optional*. A resource URL that allows the wallet to 
identify whether it has already paid for this resource.
+    Typically corresponds to the fulfillment URL.
+  :query session_id: *Optional*. Session ID that the payment must be bound to. 
 If not specified, the payment is not session-bound.
+  :query session_sig: *Optional*. Signature from the wallet to prove that it 
paid with the given session_id.  Not specified
+    if the wallet has not paid yet or still has to replay payment to bound the 
payment to the session id.
+
+  **Response:**
+
+  Returns a `CheckPaymentResponse`_, whose format can differ based on the 
status of the payment.
+
+  .. _CheckPaymentResponse:
+  .. code-block:: tsref
+
+    type CheckPaymentResponse = CheckPaymentPaidResponse | 
CheckPaymentUnpaidResponse
+
+  .. _CheckPaymentPaidResponse:
+  .. _tsref-type-CheckPaymentPaidResponse:
+  .. code-block:: tsref
+
+    interface CheckPaymentPaidResponse {
+      paid: true;
+
+      // Was the payment refunded (even partially)
+      refunded: boolean;
+
+      // Amount that was refunded
+      refund_amount: Amount;
+
+      // Contract terms
+      contract_terms: ContractTerms;
+    }
+
+  .. _CheckPaymentUnpaidResponse:
+  .. _tsref-type-CheckPaymentUnpaidResponse:
+  .. code-block:: tsref
+
+    interface CheckPaymentUnpaidResponse {
+      paid: false;
+
+      // URL to redirect the customer to pay,
+      // replay payment or confirm that the payment
+      // is bound to a session.
+      payment_redirect_url: string;
+    }
+
+
+--------------
+Giving Refunds
+--------------
+
+
+.. http:post:: /refund
+
+  Increase the refund amount associated with a given order.  The user should be
+  redirected to the `refund_redirect_url` to trigger refund processing in the 
wallet.
+
+  **Request**
+
+  The request body is a `RefundRequest`_ object.
+
+  **Response**
+
+  :status 200 OK:
+    The refund amount has been increased, the backend responds with a 
`MerchantRefundResponse`_
+  :status 400 Bad request:
+    The refund amount is not consistent: it is not bigger than the previous 
one.
+
+  .. _RefundRequest:
+  .. code-block:: tsref
+
+    interface RefundRequest {
+      // Order id of the transaction to be refunded
+      order_id: string;
+
+      // Amount to be refunded
+      refund: Amount;
+
+      // Human-readable refund justification
+      reason: string;
+
+      // Merchant instance issuing the request
+      instance?: string;
+    }
+
+  .. _MerchantRefundResponse:
+  .. code-block:: tsref
+
+    interface MerchantRefundResponse {
+      // Public key of the merchant
+      merchant_pub: string;
+
+
+      // Contract terms hash of the contract that
+      // is being refunded.
+      h_contract_terms: string;
+
+      // The signed refund permissions, to be sent to the exchange.
+      refund_permissions: MerchantRefundPermission[];
+
+      // URL (handled by the backend) that will
+      // trigger refund processing in the browser/wallet
+      refund_redirect_url: string;
+    }
+
+  .. _MerchantRefundPermission:
+  .. _tsref-type-MerchantRefundPermissoin:
+  .. code-block:: tsref
+
+    interface MerchantRefundPermission {
+      // Amount to be refunded.
+      refund_amount: AmountJson;
+
+      // Fee for the refund.
+      refund_fee: AmountJson;
+
+      // Public key of the coin being refunded.
+      coin_pub: string;
+
+      // Refund transaction ID between merchant and exchange.
+      rtransaction_id: number;
+
+      // Signature made by the merchant over the refund permission.
+      merchant_sig: string;
+    }
+
+
+--------------------
+Giving Customer Tips
+--------------------
+
+
+.. http:post:: /tip-authorize
+
+  Authorize a tip that can be picked up by the customer's wallet by POSTing to
+  `/tip-pickup`.  Note that this is simply the authorization step the back
+  office has to trigger first.  The user should be navigated to the 
`tip_redirect_url`
+  to trigger tip processing in the wallet.
+
+  **Request**
+
+  The request body is a `TipCreateRequest`_ object.
+
+  **Response**
+
+  :status 200 OK:
+    A tip has been created. The backend responds with a 
`TipCreateConfirmation`_
+  :status 404 Not Found:
+    The instance is unknown to the backend, expired or was never enabled or
+    the reserve is unknown to the exchange or expired (see detailed status
+    either being TALER_EC_RESERVE_STATUS_UNKNOWN or
+    TALER_EC_TIP_AUTHORIZE_INSTANCE_UNKNOWN or
+    TALER_EC_TIP_AUTHORIZE_INSTANCE_DOES_NOT_TIP or
+    TALER_EC_TIP_AUTHORIZE_RESERVE_EXPIRED.
+  :status 412 Precondition Failed:
+    The tip amount requested exceeds the available reserve balance for tipping.
+
+  .. _TipCreateRequest:
+  .. code-block:: tsref
+
+    interface TipCreateRequest {
+      // Amount that the customer should be tipped
+      amount: Amount;
+
+      // Merchant instance issuing the request
+      instance?: string;
+
+      // Justification for giving the tip
+      justification: string;
+
+      // URL that the user should be directed to after tipping,
+      // will be included in the tip_token.
+      next_url: string;
+    }
+
+  .. _TipCreateConfirmation:
+  .. code-block:: tsref
+
+    interface TipCreateConfirmation {
+      // Token that will be handed to the wallet,
+      // contains all relevant information to accept
+      // a tip.
+      tip_token: string;
+
+      // URL that will directly trigger procesing
+      // the tip when the browser is redirected to it
+      tip_redirect_url: string;
+    }
+
+
+.. http:post:: /tip-query
+
+  Query the status of an instance's tipping reserve.
+
+  **Request**
+
+  :query instance: instance to query
+
+  **Response**
+
+  :status 200 OK:
+    A tip has been created. The backend responds with a `TipQueryResponse`_
+  :status 404 Not Found:
+    The instance is unknown to the backend.
+  :status 412 Precondition Failed:
+    The instance does not have a tipping reserve configured.
+
+  .. _TipQueryResponse:
+  .. code-block:: tsref
+
+    interface TipQueryResponse {
+      // Amount still available
+      amount_available: Amount;
+
+      // Amount that we authorized for tips
+      amount_authorized: Amount;
+
+      // Amount that was picked up by users already
+      amount_picked_up: Amount;
+
+      // Timestamp indicating when the tipping reserve will expire
+      expiration: Timestamp;
+
+      // Reserve public key of the tipping reserve
+      reserve_pub: string;
+    }
+
+
+------------------------
+Tracking Wire Transfers
+------------------------
+
+.. http:get:: /track/transfer
+
+  Provides deposits associated with a given wire transfer.
+
+  **Request**
+
+  :query wtid: raw wire transfer identifier identifying the wire transfer (a 
base32-encoded value)
+  :query wire_method: name of the wire transfer method used for the wire 
transfer
+  :query exchange: base URL of the exchange that made the wire transfer
+  :query instance: (optional) identificative token of the merchant `instance 
<https://docs.taler.net/operate-merchant.html#instances-lab>`_ which is being 
tracked.
+
+  **Response:**
+
+  :status 200 OK:
+    The wire transfer is known to the exchange, details about it follow in the 
body.
+    The body of the response is a `MerchantTrackTransferResponse`_.  Note that
+    the similarity to the response given by the exchange for a /track/transfer
+    is completely intended.
+
+  :status 404 Not Found:
+    The wire transfer identifier is unknown to the exchange.
+
+  :status 424 Failed Dependency: The exchange provided conflicting information 
about the transfer. Namely,
+    there is at least one deposit among the deposits aggregated by `wtid` that 
accounts for a coin whose
+    details don't match the details stored in merchant's database about the 
same keyed coin.
+    The response body contains the `TrackTransferConflictDetails`_.
+
+  .. _MerchantTrackTransferResponse:
+  .. _tsref-type-TrackTransferResponse:
+  .. code-block:: tsref
+
+    interface TrackTransferResponse {
+      // Total amount transferred
+      total: Amount;
+
+      // Applicable wire fee that was charged
+      wire_fee: Amount;
+
+      // public key of the merchant (identical for all deposits)
+      merchant_pub: EddsaPublicKey;
+
+      // hash of the wire details (identical for all deposits)
+      H_wire: HashCode;
+
+      // Time of the execution of the wire transfer by the exchange
+      execution_time: Timestamp;
+
+      // details about the deposits
+      deposits_sums: TrackTransferDetail[];
+
+      // signature from the exchange made with purpose
+      // `TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT`
+      exchange_sig: EddsaSignature;
+
+      // public EdDSA key of the exchange that was used to generate the 
signature.
+      // Should match one of the exchange's signing keys from /keys.  Again 
given
+      // explicitly as the client might otherwise be confused by clock skew as 
to
+      // which signing key was used.
+      exchange_pub: EddsaSignature;
+    }
+
+  .. _tsref-type-TrackTransferDetail:
+  .. code-block:: tsref
+
+    interface TrackTransferDetail {
+      // Business activity associated with the wire transferred amount
+      // `deposit_value`.
+      order_id: string;
+
+      // The total amount the exchange paid back for `order_id`.
+      deposit_value: Amount;
+
+      // applicable fees for the deposit
+      deposit_fee: Amount;
+    }
+
+
+  **Details:**
+
+  .. _tsref-type-TrackTransferConflictDetails:
+  .. _TrackTransferConflictDetails:
+  .. code-block:: tsref
+
+    interface TrackTransferConflictDetails {
+      // Numerical `error code <error-codes>`_
+      code: number;
+
+      // Text describing the issue for humans.
+      hint: String;
+
+      // A /deposit response matching `coin_pub` showing that the
+      // exchange accepted `coin_pub` for `amount_with_fee`.
+      exchange_deposit_proof: DepositSuccess;
+
+      // Offset in the `exchange_transfer_proof` where the
+      // exchange's response fails to match the `exchange_deposit_proof`.
+      conflict_offset: number;
+
+      // The response from the exchange which tells us when the
+      // coin was returned to us, except that it does not match
+      // the expected value of the coin.
+      exchange_transfer_proof: TrackTransferResponse;
+
+      // Public key of the coin for which we have conflicting information.
+      coin_pub: EddsaPublicKey;
+
+      // Merchant transaction in which `coin_pub` was involved for which
+      // we have conflicting information.
+      transaction_id: number;
+
+      // Expected value of the coin.
+      amount_with_fee: Amount;
+
+      // Expected deposit fee of the coin.
+      deposit_fee: Amount;
+
+    }
+
+
+.. http:get:: /track/transaction
+
+  Provide the wire transfer identifier associated with an (existing) deposit 
operation.
+
+  **Request:**
+
+  :query id: ID of the transaction we want to trace (an integer)
+  :query instance:  merchant instance
+
+  **Response:**
+
+  :status 200 OK:
+    The deposit has been executed by the exchange and we have a wire transfer 
identifier.
+    The response body is a JSON array of `TransactionWireTransfer`_ objects.
+  :status 202 Accepted:
+    The deposit request has been accepted for processing, but was not yet
+    executed.  Hence the exchange does not yet have a wire transfer identifier.
+    The merchant should come back later and ask again.
+    The response body is a :ref:`TrackTransactionAcceptedResponse 
<TrackTransactionAcceptedResponse>`.  Note that
+    the similarity to the response given by the exchange for a /track/order
+    is completely intended.
+  :status 404 Not Found: The transaction is unknown to the backend.
+  :status 424 Failed Dependency:
+    The exchange previously claimed that a deposit was not included in a wire
+    transfer, and now claims that it is.  This means that the exchange is
+    dishonest.  The response contains the cryptographic proof that the exchange
+    is misbehaving in the form of a `TransactionConflictProof`_.
+
+  **Details:**
+
+  .. _tsref-type-TransactionWireTransfer:
+  .. _TransactionWireTransfer:
+  .. code-block:: tsref
+
+    interface TransactionWireTransfer {
+
+      // Responsible exchange
+      exchange_uri: string;
+
+      // 32-byte wire transfer identifier
+      wtid: Base32;
+
+      // execution time of the wire transfer
+      execution_time: Timestamp;
+
+      // Total amount that has been wire transfered
+      // to the merchant
+      amount: Amount;
+    }
+
+  .. _tsref-type-CoinWireTransfer:
+  .. _CoinWireTransfer:
+  .. code-block:: tsref
+
+    interface CoinWireTransfer {
+      // public key of the coin that was deposited
+      coin_pub: EddsaPublicKey;
+
+      // Amount the coin was worth (including deposit fee)
+      amount_with_fee: Amount;
+
+      // Deposit fee retained by the exchange for the coin
+      deposit_fee: Amount;
+    }
+
+  .. _TransactionConflictProof:
+  .. _tsref-type-TransactionConflictProof:
+  .. code-block:: tsref
+
+    interface TransactionConflictProof {
+      // Numerical `error code <error-codes>`_
+      code: number;
+
+      // Human-readable error description
+      hint: string;
+
+      // A claim by the exchange about the transactions associated
+      // with a given wire transfer; it does not list the
+      // transaction that `transaction_tracking_claim` says is part
+      // of the aggregate.  This is
+      // a `/track/transfer` response from the exchange.
+      wtid_tracking_claim: TrackTransferResponse;
+
+      // The current claim by the exchange that the given
+      // transaction is included in the above WTID.
+      // (A response from `/track/order`).
+      transaction_tracking_claim: TrackTransactionResponse;
+
+      // Public key of the coin for which we got conflicting information.
+      coin_pub: CoinPublicKey;
+
+    }
+
+
+-------------------
+Transaction history
+-------------------
+
+.. http:get:: /history
+
+  Returns transactions up to some point in the past
+
+  **Request**
+
+  :query date: time threshold, see `delta` for its interpretation.
+  :query start: row number threshold, see `delta` for its interpretation.  
Defaults to `UINT64_MAX`, namely the biggest row id possible in the database.
+  :query delta: takes value of the form `N (-N)`, so that at most `N` values 
strictly younger (older) than `start` and `date` are returned.  Defaults to 
`-20`.
+  :query instance: on behalf of which merchant instance the query should be 
accomplished.
+  :query ordering: takes value `descending` or `ascending` according to the 
results wanted from younger to older or vice versa.  Defaults to `descending`.
+
+  **Response**
+
+  :status 200 OK: The response is a JSON `array` of  `TransactionHistory`_.  
The array is sorted such that entry `i` is younger than entry `i+1`.
+
+  .. _tsref-type-TransactionHistory:
+  .. _TransactionHistory:
+  .. code-block:: tsref
+
+    interface TransactionHistory {
+      // The serial number this entry has in the merchant's DB.
+      row_id: number;
+
+      // order ID of the transaction related to this entry.
+      order_id: string;
+
+      // Transaction's timestamp
+      timestamp: Timestamp;
+
+      // Total amount associated to this transaction.
+      amount: Amount;
+    }
+
+.. _proposal:
+
+
+-------------------------
+Dynamic Merchant Instance
+-------------------------
+
+.. note::
+
+    The endpoints to dynamically manage merchant instances has not been
+    implemented yet. The bug id for this refernce is 5349.
+
+.. http:get:: /instances
+
+  This is used to return the list of all the merchant instances
+
+  **Response**
+
+  :status 200 OK:
+    The backend has successfully returned the list of instances stored. Returns
+    a `InstancesResponse`_.
+
+  .. _InstancesResponse:
+  .. code-block:: tsref
+
+    interface InstancesResponse {
+      // List of instances that are present in the backend(see `below 
<Instance>`_)
+      instances: Instance[];
+    }
+
+The `instance` object describes the instance registered with the backend. It 
has the following structure:
+
+  .. Instance:
+  .. _tsref-type-Instance:
+  .. code-block:: tsref
+
+    interface Instance {
+      // Merchant name corresponding to this instance.
+      name: string;
+
+      // The URL where the wallet will send coins.
+      payto: string;
+
+      // Merchant instance of the response to create
+      instance: string;
+
+      //unique key for each merchant
+      merchant_id: string;
+    }
+
+
+.. http:put:: /instances/
+
+  This request will be used to create a new merchant instance in the backend.
+
+  **Request**
+
+  The request must be a `CreateInstanceRequest`_.
+
+  **Response**
+
+  :status 200 OK:
+    The backend has successfully created the instance.  The response is a
+    `CreateInstanceResponse`_.
+
+  .. _CreateInstanceRequest:
+  .. code-block:: tsref
+
+    interface CreateInstanceRequest {
+      // The URL where the wallet has to send coins.
+      // payto://-URL of the merchant's bank account. Required.
+      payto: string;
+
+      // Merchant instance of the response to create
+      // This field is optional. If it is not specified
+      // then it will automatically be created.
+      instance?: string;
+
+      // Merchant name corresponding to this instance.
+      name: string;
+
+    }
+
+  .. _CreateInstanceResponse:
+  .. code-block:: tsref
+
+    interface CreateInstanceResponse {
+      // Merchant instance of the response that was created
+      instance: string;
+
+      //unique key for each merchant
+      merchant_id: string;
+    }
+
+
+.. http:get:: /instances/<instance-id>
+
+  This is used to query a specific merchant instance.
+
+  **Request:**
+
+  :query instance_id: instance id that should be used for the instance
+
+  **Response**
+
+  :status 200 OK:
+    The backend has successfully returned the list of instances stored. Returns
+    a `QueryInstancesResponse`_.
+
+  .. _QueryInstancesResponse:
+  .. code-block:: tsref
+
+    interface QueryInstancesResponse {
+      // The URL where the wallet has to send coins.
+      // payto://-URL of the merchant's bank account. Required.
+      payto: string;
+
+      // Merchant instance of the response to create
+      // This field is optional. If it is not specified
+      // then it will automatically be created.
+      instance?: string;
+
+      // Merchant name corresponding to this instance.
+      name: string;
+
+    }
+
+
+.. http:post:: /instances/<instance-id>
+
+  This request will be used to update merchant instance in the backend.
+
+
+  **Request**
+
+  The request must be a `PostInstanceUpdateRequest`_.
+
+  **Response**
+
+  :status 200 OK:
+    The backend has successfully updated the instance.  The response is a
+    `PostInstanceUpdateResponse`_.
+
+  .. _PostInstanceUpdateRequest:
+  .. code-block:: tsref
+
+    interface PostInstanceUpdateRequest {
+      // Merchant instance that is to be updaated. Required.
+      instance: string;
+
+      // New URL where the wallet has to send coins.
+      // payto://-URL of the merchant's bank account. Required.
+      payto: string;
+
+      // Merchant name coreesponding to this instance.
+      name: string;
+
+    }
+
+  .. _PostInstanceUpdateResponse:
+  .. code-block:: tsref
+
+    interface PostInstanceUpdateResponse {
+      // Merchant instance of the response that was updated
+      instance: string;
+
+      //unique key for each merchant
+      merchant_id: string;
+    }
+
+
+.. http:delete:: /instances/<instance-id>
+
+  This request will be used to delete merchant instance in the backend.
+
+  **Request:**
+
+  :query instance_id: instance id that should be used for the instance
+
+  **Response**
+
+  :status 200 OK:
+    The backend has successfully removed the instance.  The response is a
+    `PostInstanceRemoveResponse`_.
+
+  .. _PostInstanceRemoveResponse:
+  .. code-block:: tsref
+
+    interface PostInstanceRemoveResponse {
+      deleted: true;
+    }
+
+
+------------------
+The Contract Terms
+------------------
+
+The `contract terms` must have the following structure:
+
+  .. _ContractTerms:
+  .. _tsref-type-ContractTerms:
+  .. code-block:: tsref
+
+    interface ContractTerms {
+      // Human-readable description of the whole purchase
+      summary: string;
+
+      // Unique, free-form identifier for the proposal.
+      // Must be unique within a merchant instance.
+      // For merchants that do not store proposals in their DB
+      // before the customer paid for them, the order_id can be used
+      // by the frontend to restore a proposal from the information
+      // encoded in it (such as a short product identifier and timestamp).
+      order_id: string;
+
+      // Total price for the transaction.
+      // The exchange will subtract deposit fees from that amount
+      // before transfering it to the merchant.
+      amount: Amount;
+
+      // The URL where the wallet has to send coins.
+      pay_url: string;
+
+      // The URL for this purchase.  Every time is is visited, the merchant
+      // will send back to the customer the same proposal.  Clearly, this URL
+      // can be bookmarked and shared by users.
+      fulfillment_url: string;
+
+      // Maximum total deposit fee accepted by the merchant for this contract
+      max_fee: Amount;
+
+      // Maximum wire fee accepted by the merchant (customer share to be
+      // divided by the 'wire_fee_amortization' factor, and further reduced
+      // if deposit fees are below 'max_fee').  Default if missing is zero.
+      max_wire_fee: Amount;
+
+      // Over how many customer transactions does the merchant expect to
+      // amortize wire fees on average?  If the exchange's wire fee is
+      // above 'max_wire_fee', the difference is divided by this number
+      // to compute the expected customer's contribution to the wire fee.
+      // The customer's contribution may further be reduced by the difference
+      // between the 'max_fee' and the sum of the actual deposit fees.
+      // Optional, default value if missing is 1.  0 and negative values are
+      // invalid and also interpreted as 1.
+      wire_fee_amortization: Integer;
+
+      // List of products that are part of the purchase (see `below 
<Product>`_)
+      products: Product[];
+
+      // Time when this contract was generated
+      timestamp: Timestamp;
+
+      // After this deadline has passed, no refunds will be accepted.
+      refund_deadline: Timestamp;
+
+      // After this deadline, the merchant won't accept payments for the 
contact
+      pay_deadline: Timestamp;
+
+      // Merchant's public key used to sign this proposal; this information
+      // is typically added by the backend Note that this can be an ephemeral 
key.
+      merchant_pub: EddsaPublicKey;
+
+      // More info about the merchant, see below
+      merchant: Merchant;
+
+      // The hash of the merchant instance's wire details.
+      H_wire: HashCode;
+
+      // Wire transfer method identifier for the wire method associated with 
H_wire.
+      // The wallet may only select exchanges via a matching auditor if the
+      // exchange also supports this wire method.
+      // The wire transfer fees must be added based on this wire transfer 
method.
+      wire_method: string;
+
+      // Any exchanges audited by these auditors are accepted by the merchant.
+      auditors: Auditor[];
+
+      // Exchanges that the merchant accepts even if it does not accept any 
auditors that audit them.
+      exchanges: Exchange[];
+
+      // Map from labels to locations
+      locations: { [label: string]: [location: Location], ... };
+
+      // Nonce generated by the wallet and echoed by the merchant
+      // in this field when the proposal is generated.
+      nonce: string;
+
+      // Extra data that is only interpreted by the merchant frontend.
+      // Useful when the merchant needs to store extra information on a
+      // contract without storing it separately in their database.
+      extra?: any;
+    }
+
+  The wallet must select a exchange that either the mechant accepts directly by
+  listing it in the exchanges arry, or for which the merchant accepts an 
auditor
+  that audits that exchange by listing it in the auditors array.
+
+  The `product` object describes the product being purchased from the 
merchant. It has the following structure:
+
+  .. _Product:
+  .. _tsref-type-Product:
+  .. code-block:: tsref
+
+    interface Product {
+      // Human-readable product description.
+      description: string;
+
+      // The quantity of the product to deliver to the customer (optional, if 
applicable)
+      quantity?: string;
+
+      // The price of the product; this is the total price for the amount 
specified by `quantity`
+      price: Amount;
+
+      // merchant-internal identifier for the product
+      product_id?: string;
+
+      // a list of objects indicating a `taxname` and its amount. Again, 
italics denotes the object field's name.
+      taxes?: any[];
+
+      // time indicating when this product should be delivered
+      delivery_date: Timestamp;
+
+      // where to deliver this product. This may be an URL for online delivery
+      // (i.e. `http://example.com/download` or `mailto:address@hidden`),
+      // or a location label defined inside the proposition's `locations`.
+      // The presence of a colon (`:`) indicates the use of an URL.
+      delivery_location: string;
+    }
+
+  .. _tsref-type-Merchant:
+  .. code-block:: ts
+
+    interface Merchant {
+      // label for a location with the business address of the merchant
+      address: string;
+
+      // the merchant's legal name of business
+      name: string;
+
+      // label for a location that denotes the jurisdiction for disputes.
+      // Some of the typical fields for a location (such as a street address) 
may be absent.
+      jurisdiction: string;
+
+      // Which instance is working this proposal.
+      // See `Merchant Instances 
<https://docs.taler.net/operate-merchant.html#instances-lab>`_.
+      // This field is optional, as the "default" instance is not forced to 
provide any
+      // `instance` identificator.
+      instance: string;
+    }
+
+
+  .. _tsref-type-Location:
+  .. _Location:
+  .. code-block:: ts
+
+    interface Location {
+      country?: string;
+      city?: string;
+      state?: string;
+      region?: string;
+      province?: string;
+      zip_code?: string;
+      street?: string;
+      street_number?: string;
+    }
+
+  .. _tsref-type-Auditor:
+  .. code-block:: tsref
+
+    interface Auditor {
+      // official name
+      name: string;
+
+      // Auditor's public key
+      auditor_pub: EddsaPublicKey;
+
+      // Base URL of the auditor
+      url: string;
+    }
+
+  .. _tsref-type-Exchange:
+  .. code-block:: tsref
+
+    interface Exchange {
+      // the exchange's base URL
+      url: string;
+
+      // master public key of the exchange
+      master_pub: EddsaPublicKey;
+    }
+
+
+-------------------
+Customer-facing API
+-------------------
+
+The `/public/*` endpoints are publicly exposed on the internet and accessed
+both by the user's browser and their wallet.
+
+
+.. http:post:: /public/pay
+
+  Pay for a proposal by giving a deposit permission for coins.  Typically used 
by
+  the customer's wallet.  Can also be used in `abort-refund` mode to refund 
coins
+  that were already deposited as part of a failed payment.
+
+  **Request:**
+
+  The request must be a :ref:`pay request <PayRequest>`.
+
+  **Response:**
+
+  :status 200 OK:
+    The exchange accepted all of the coins. The body is a `PaymentResponse`_ 
if the request used the mode "pay", or a `MerchantRefundResponse`_ if the 
request used was the mode "abort-refund".
+    The `frontend` should now fullfill the contract.
+  :status 412 Precondition Failed:
+    The given exchange is not acceptable for this merchant, as it is not in the
+    list of accepted exchanges and not audited by an approved auditor.
+  :status 401 Unauthorized:
+    One of the coin signatures was not valid.
+  :status 403 Forbidden:
+    The exchange rejected the payment because a coin was already spent before.
+    The response will include the `coin_pub` for which the payment failed,
+    in addition to the response from the exchange to the `/deposit` request.
+
+  The `backend` will return verbatim the error codes received from the 
exchange's
+  :ref:`deposit <deposit>` API.  If the wallet made a mistake, like by
+  double-spending for example, the `frontend` should pass the reply verbatim to
+  the browser/wallet. This should be the expected case, as the `frontend`
+  cannot really make mistakes; the only reasonable exception is if the
+  `backend` is unavailable, in which case the customer might appreciate some
+  reassurance that the merchant is working on getting his systems back online.
+
+  .. _PaymentResponse:
+  .. code-block:: tsref
+
+    interface PaymentResponse {
+      // Signature on `TALER_PaymentResponsePS`_ with the public
+      // key of the instance in the proposal.
+      sig: EddsaSignature;
+
+      // Proposal data hash being signed over
+      h_proposal_data: HashCode;
+
+      // Proposal, send for convenience so the frontend
+      // can do order processing without a second lookup on
+      // a successful payment
+      proposal: Proposal;
+    }
+
+
+  .. _tsref-type-Proposal:
+  .. code-block:: tsref
+
+    interface Proposal {
+      // The proposal data, effectively the frontend's order with some data 
filled in
+      // by the merchant backend.
+      data: ProposalData;
+
+      // Contract's hash, provided as a convenience.  All components that do
+      // not fully trust the merchant must verify this field.
+      H_proposal: HashCode;
+
+      // Signature over the hashcode of `proposal` made by the merchant.
+      merchant_sig: EddsaSignature;
+    }
+
+
+  .. _PayRequest:
+  .. code-block:: tsref
+
+    interface PayRequest {
+      // Signature on `TALER_PaymentResponsePS`_ with the public
+      // key of the instance in the proposal.
+      sig: EddsaSignature;
+
+      // Proposal data hash being signed over
+      h_proposal_data: HashCode;
+
+      // Proposal, send for convenience so the frontend
+      // can do order processing without a second lookup on
+      // a successful payment
+      proposal: Proposal;
+
+      // Coins with signature.
+      coins: CoinPaySig[];
+
+      // The merchant public key, used to uniquely
+      // identify the merchant instance.
+      merchant_pub: string;
+
+      // Order ID that's being payed for.
+      order_id: string;
+
+      // Mode for /pay ("pay" or "abort-refund")
+      mode: "pay" | "abort-refund";
+    }
+
+
+.. http:get:: /public/proposal
+
+  Retrieve and take ownership (via nonce) over a proposal.
+
+  **Request**
+
+  :query instance: the merchant instance issuing the request
+  :query order_id: the order id whose refund situation is being queried
+  :query nonce: the nonce for the proposal
+
+  **Response**
+
+  :status 200 OK:
+    The backend has successfully retrieved the proposal.  It responds with a 
:ref:`proposal <proposal>`.
+
+  :status 403 Forbidden:
+    The frontend used the same order ID with different content in the order.
+
+
+.. http:post:: /public/tip-pickup
+
+  Handle request from wallet to pick up a tip.
+
+  **Request**
+
+  The request body is a `TipPickupRequest`_ object.
+
+  **Response**
+
+  :status 200 OK:
+    A tip is being returned. The backend responds with a `TipResponse`_
+  :status 401 Unauthorized:
+    The tip amount requested exceeds the tip.
+  :status 404 Not Found:
+    The tip identifier is unknown.
+  :status 409 Conflict:
+    Some of the denomination key hashes of the request do not match those 
currently available from the exchange (hence there is a conflict between what 
the wallet requests and what the merchant believes the exchange can provide).
+
+  .. _TipPickupRequest:
+  .. code-block:: tsref
+
+    interface TipPickupRequest {
+
+      // Identifier of the tip.
+      tip_id: HashCode;
+
+      // List of planches the wallet wants to use for the tip
+      planchets: PlanchetDetail[];
+    }
+
+    interface PlanchetDetail {
+      // Hash of the denomination's public key (hashed to reduce
+      // bandwidth consumption)
+      denom_pub_hash: HashCode;
+
+      // coin's blinded public key
+      coin_ev: CoinEnvelope;
+
+    }
+
+  .. _TipResponse:
+  .. code-block:: tsref
+
+    interface TipResponse {
+      // Public key of the reserve
+      reserve_pub: EddsaPublicKey;
+
+      // The order of the signatures matches the planchets list.
+      reserve_sigs: EddsaSignature[];
+    }
+
+
+.. http:get:: /public/refund
+
+  Pick up refunds for an order.
+
+  **Request**
+
+  :query instance: the merchant instance issuing the request
+  :query order_id: the order id whose refund situation is being queried
+
+  **Response**
+
+  If case of success, an *array of* `RefundLookup`_ objects is returned.
+
+  .. _RefundLookup:
+  .. code-block:: tsref
+
+    interface RefundLookup {
+
+      // Coin from which the refund is going to be taken
+      coin_pub: EddsaPublicKey;
+
+      // Refund amount taken from coin_pub
+      refund_amount: Amount;
+
+      // Refund fee
+      refund_fee: Amount;
+
+      // Identificator of the refund
+      rtransaction_id: number;
+
+      // Merchant public key
+      merchant_pub: EddsaPublicKey
+
+      // Merchant signature of a TALER_RefundRequestPS object
+      merchant_sig: EddsaSignature;
+    }
+
+
+.. http:get:: /public/trigger-pay
+
+  Used to trigger processing of payments, refunds and tips in the browser.  
The exact behavior
+  can be dependent on the user's browser.
diff --git a/src/api/api-sync.rst b/src/api/api-sync.rst
new file mode 100644
index 0000000..701c7df
--- /dev/null
+++ b/src/api/api-sync.rst
@@ -0,0 +1,407 @@
+..
+  This file is part of GNU TALER.
+  Copyright (C) 2018 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU General Public License as published by the Free Software
+  Foundation; either version 2.1, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
details.
+
+  You should have received a copy of the GNU Lesser General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+
+  @author Christian Grothoff
+
+.. _sync-api:
+
+=============================================
+Wallet Backup and Synchronization Service API
+=============================================
+
+The wallet backup and synchronization service uses an EdDSA wallet key
+to identify the "account" of the user.  The wallet key is Crockford
+Base32-encoded in the URI to access the data and used to sign requests
+as well as to encrypt the contents (see below).  These signatures are
+provided in detached from as HTTP headers.
+
+Once the user activates backup or synchronization, the wallet should
+display the wallet key as a QR code as well as in text format together
+with the synchronization service's URL and ask the user to print this
+key material and keep it safe.
+
+The actual format of the wallet database is not relevant for the
+backup and synchronization service, as the service must only ever see
+a padded and encrypted version of the data.
+
+However, there are a few general rules that will apply to
+any version of the wallet database.  Still, except for the
+32 byte minimum upload size, the synchronization service
+itself cannot not enforce these rules.
+
+  *  First, the database should be compressed (i.e. gzip), then
+     padded to a power of 2 in kilobytes or a multiple of
+     megabytes, then encrypted and finally protected with
+     an HDKF.
+  *  The encryption should use an ephemeral Curve25519 point that
+     is prefixed to the actual database, and combined with
+     the private wallet key via ECDH to create a symmetric secret.
+     With every revision of the wallet (but only real
+     revisions or merge operations), a fresh ephemeral must be
+     used to ensure that the symmetric secret differs every
+     time.  HKDFs are used to derive symmetric key material
+     for authenticated encryption (encrypt-then-mac or a
+     modern AEAD-cipher like Keccak).  Given that AES is more
+     easily available and will likey increase the code of
+     the wallet less, AES plus a SHA-512 HMAC should suffice
+     for now.
+  *  The wallet must enable merging databases in a way that is
+     associative and commutative.  For most activities, this implies
+     merging lists, applying expirations, dropping duplicates and
+     sorting the result.  For deletions (operations by which the user
+     removed records prior to their scheduled expiration), it means
+     keeping a summarizing log of all deletion operations and applying
+     the deletions after each merge.  A summarizing log of a deletion
+     operation would combine two deletion operations of the form
+     "delete all transactions smaller than amount X before time T" and
+     "delete all transactions smaller than amount Y before time T"
+     into "delete all transactions smaller than amount max(X,Y) before
+     time T".  Similar summarizations should be applied to all
+     deletion operations supported by the wallet.  Deletion operations
+     themselves are associated with an expiration time reflecting the
+     expiration of the longest lasting record that they explicitly
+     deleted.
+     Purchases do not have an expiration time, thus they create
+     a challenge if an indivdiual purchase is deleted. Thus, when
+     an individual purchase is deleted, the wallet is to keep track
+     of the deletion with a deletion record. The deletion record
+     still includes the purchase amount and purchase date.  Thus,
+     when purchases are deleted "in bulk" in a way that would have
+     covered the individual deletion, such deletion records may
+     still be subsumed by a more general deletion clause.  In addition
+     to the date and amount, the deletion record should only contain
+     a salted hash of the original purchase record's primary key,
+     so as to minimize information leakage.
+  *  The database should contain a "last modified" timestamp to ensure
+     we do not go backwards in time if the synchronization service is
+     malicious.  Merging two databases means taking the max of the
+     "last modified" timestamps, not setting it to the current time.
+     The wallet should reject a "fast forward" database update if the
+     result would imply going back in time.  If the wallet receives a
+     database with a timestamp into the future, it must still
+     increment it by the smallest possible amount when uploading an
+     update.
+
+It is assumed that the synchronization service is only ever accessed
+over TLS, and that the synchronization service is trusted to not build
+user's location profiles by linking client IP addresses and wallet
+keys.
+
+
+--------------------------
+Receiving Terms of Service
+--------------------------
+
+.. http:get:: /terms
+
+  Obtain the terms of service provided by the storage service.
+
+  **Response:**
+
+  Returns a `SyncTermsOfServiceResponse`_.
+
+  .. _SyncTermsOfServiceResponse:
+  .. _tsref-type-SyncTermsOfServiceResponse:
+  .. code-block:: tsref
+
+    interface SyncTermsOfServiceResponse {
+      // maximum wallet database backup size supported
+      storage_limit_in_megabytes: number;
+
+      // maximum number of sync requests per day (per account)
+      daily_sync_limit: number;
+
+      // how long after an account (or device) becomes dormant does the
+      // service expire the respective records?
+      inactive_expiration: relative-time;
+
+      // Fee for an account, per year.
+      annual_fee: Amount;
+
+    }
+
+
+.. http:get:: /salt
+
+  Obtain the salt used by the storage service.
+
+
+  **Response:**
+
+  Returns a `SaltResponse`_.
+
+  .. _SaltResponse:
+  .. _tsref-type-SaltResponse:
+  .. code-block:: tsref
+
+    interface SaltResponse {
+      // salt value, at least 128 bits of entropy
+      salt: string;
+    }
+
+
+.. _sync:
+
+.. http:get:: /$WALLET-KEY
+
+  Download latest version of the wallet database.
+  The returned headers must include "Etags" based on
+  the hash of the (encrypted) database. The server must
+  check the client's caching headers and only return the
+  full database if it has changed since the last request
+  of the client.
+
+  This method is generally only performed once per device
+  when the private key and URL of a synchronization service are
+  first given to the wallet on the respective device.  Once a
+  wallet has a database, it should always use the POST method.
+
+  A signature is not required, as (1) the wallet-key should
+  be reasonably private and thus unauthorized users should not
+  know how to produce the correct request, and (2) the
+  information returned is encrypted to the private key anyway
+  and thus virtually useless even to an attacker who somehow
+  managed to obtain the public key.
+
+  **Response**
+
+  :status 200 OK:
+    The body contains the current version of the wallet's
+    database as known to the server.
+
+  :status 204 No content:
+    This is a fresh account, no previous wallet data exists at
+    the server.
+
+  :status 402 Payment required:
+    The synchronization service requires payment before the
+    account can continue to be used.  The fulfillment URL
+    should be the /$WALLET-KEY URL, but can be safely ignored
+    by the wallet.  The contract should be shown to the user
+    in the canonical dialog, possibly in a fresh tab.
+
+  :status 410 Gone:
+    The backup service has closed operations.  The body will
+    contain the latest version still available at the server.
+    The body may be empty if no version is available.
+    The user should be urged to find another provider.
+
+  :status 429 Too many requests:
+    This account has exceeded daily thresholds for the number of
+    requests.  The wallet should try again later, and may want
+    to decrease its synchronization frequency.
+
+  .. note::
+
+    "200 OK" responses include an HTTP header
+    "X-Taler-Sync-Signature" with the signature of the
+    wallet from the orginal upload, and an
+    "X-Taler-Sync-Previous" with the version that was
+    being updated (unless this is the first revision).
+    "X-Taler-Sync-Previous" is only given to enable
+    signature validation.
+
+
+.. http:post:: /$WALLET-KEY
+
+  Upload a new version of the wallet's database, or download the
+  latest version.  The request must include the "Expect: 100 Continue"
+  header.  The client must wait for "100 Continue" before proceeding
+  with the upload, regardless of the size of the upload.
+
+  **Request**
+
+  The request must include a "If-Match" header indicating the latest
+  version of the wallet's database known to the client.  If the server
+  knows a more recent version, it will respond with a "409 conflict"
+  and return the server's version in the response.  The client must
+  then merge the two versions before retrying the upload.  Note that
+  a "409 Conflict" response will typically be given before the upload,
+  (instead of "100 continue"), but may also be given after the upload,
+  for example due to concurrent activities from other wallets on the
+  same account!
+
+  The request must also include an "X-Taler-Sync-Signature" signing
+  the "If-Match" SHA-512 value and the SHA-512 hash of the body with
+  the wallet private key.
+
+  Finally, the SHA-512 hash of the body must also be given in an
+  "E-tag" header of the request (so that the signature can be verified
+  before the upload is allowed to proceed).  We note that the use
+  of "E-tag" in HTTP requests is non-standard, but in this case
+  logical.
+
+  The uploaded body must have at least 32 bytes of payload (see
+  suggested upload format beginning with an ephemeral key).
+
+
+  **Response**
+
+  :status 204 No content:
+    The transfer was successful, and the server has registered
+    the new version.
+
+  :status 304 Not modified:
+    The server is already aware of this version of the wallet.
+    Returned before 100 continue to avoid upload.
+
+  :status 400 Bad request:
+    Most likely, the uploaded body is too short (less than 32 bytes).
+
+  :status 401 Unauthorized:
+    The signature is invalid or missing (or body does not match).
+
+  :status 402 Payment required:
+    The synchronization service requires payment before the
+    account can continue to be used.  The fulfillment URL
+    should be the /$WALLET-KEY URL, but can be safely ignored
+    by the wallet.  The contract should be shown to the user
+    in the canonical dialog, possibly in a fresh tab.
+
+  :status 409 Conflict:
+    The server has a more recent version than what is given
+    in "If-Match".  The more recent version is returned. The
+    client should merge the two versions and retry using the
+    given response's "E-Tag" in the next attempt in "If-Match".
+
+  :status 410 Gone:
+    The backup service has closed operations.  The body will
+    contain the latest version still available at the server.
+    The body may be empty if no version is available.
+    The user should be urged to find another provider.
+
+  :status 411 Length required:
+    The client must specify the "Content-length" header before
+    attempting upload.  While technically optional by the
+    HTTP specification, the synchronization service may require
+    the client to provide the length upfront.
+
+  :status 413 Request Entity Too Large:
+    The requested upload exceeds the quota for the type of
+    account.  The wallet should suggest to the user to
+    migrate to another backup and synchronization service
+    (like with "410 Gone").
+
+  :status 429 Too many requests:
+    This account has exceeded daily thresholds for the number of
+    requests.  The wallet should try again later, and may want
+    to decrease its synchronization frequency.
+
+  .. note::
+
+    Responses with a body include an HTTP header
+    "X-Taler-Sync-Signature" with the signature of the
+    wallet from the orginal upload, and an
+    "X-Taler-Sync-Previous" with the version that was
+    being updated (unless this is the first revision).
+    "X-Taler-Sync-Previous" is only given to enable
+    signature validation.
+
+
+
+---------------------------
+Special constraints for Tor
+---------------------------
+
+We might introduce the notion of a "constraint" into the wallet's
+database that states that the database is a "Tor wallet".  Then,
+synchronizing a "Tor-wallet" with a non-Tor wallet should trigger a
+stern warning and require user confirmation (as otherwise
+cross-browser synchronization may weaken the security of Tor browser
+users).
+
+
+------------------------------------------------
+Discovery of backup and synchronization services
+------------------------------------------------
+
+The wallet should keep a list of "default" synchronization services
+per currency (by the currency the synchronization service accepts
+for payment).  If a synchronization service is entirely free, it
+should be kept in a special list that is always available.
+
+Extending (or shortening) the list of synchronization services should
+be possible using the same mechanism that is used to add/remove
+auditors or exchanges.
+
+The wallet should urge the user to make use of a synchronization
+service upon first withdrawal, suggesting one that is free or
+accepts payment in the respective currency. If none is available,
+the wallet should warn the user about the lack of availalable
+backups and synchronization and suggest to the user to find a
+reasonable service.  Once a synchronization service was selected,
+the wallet should urge the user to print the respective key
+material.
+
+When the wallet starts the first time on a new device, it should
+ask the user if he wants to synchronize with an existing wallet,
+and if so, ask the user to enter the respective key and the
+(base) URL of the synchronization service.
+
+
+-------------------------
+Synchronization frequency
+-------------------------
+
+Generally, the wallet should attempt to synchronize at a randomized
+time interval between 30 and 300 seconds of being started, unless it
+already synchronized less than two hours ago already.  Afterwards,
+the wallet should synchronize every two hours, or after purchases
+exceed 5 percent of the last bulk amount that the user withdrew.
+In all cases the exact time of synchronization should be randomized
+between 30 and 300 seconds of the specified event, both to minimize
+obvious correlations and to spread the load.
+
+If the two hour frequency would exceed half of the rate budget offered
+by the synchronization provider, it should be reduced to remain below
+that threshold.
+
+
+-------------------------------
+Synchronization user experience
+-------------------------------
+
+The menu should include three entries for synchronization:
+
+* "synchronize" to manually trigger synchronization,
+    insensitive if no synchronization provider is available
+* "export backup configuration" to re-display (and possibly
+   print) the synchronization and backup parameters (URL and
+   private key), insensitive if no synchronization
+   provider is available, and
+* "import backup configuration" to:
+
+  * import another devices' synchronization options
+    (by specifying URL and private key, or possibly
+    scanning a QR code), or
+  * select a synchronization provider from the list,
+    including manual specification of a URL; here
+    confirmation should only be possible if the provider
+    is free or can be paid for; in this case, the
+    wallet should trigger the payment interaction when
+    the user presses the "select" button.
+  * a special button to "disable synchronization and backup"
+
+One usability issue here is that we are asking users to deal with a
+private key.  It is likely better to map private keys to trustwords
+(PEP-style).  Also, when putting private keys into a QR code, there is
+the danger of the QR code being scanned and interpreted as a "public"
+URL.  Thus, the QR code should use the schema
+"taler-sync://$SYNC-DOMAIN/$SYNC-PATH#private-key" where
+"$SYNC-DOMAIN" is the domainname of the synchronization service and
+$SYNC-PATH the (usually empty) path.  By putting the private key after
+"#", we may succeed in disclosing the value even to eager Web-ish
+interpreters of URLs.  Note that the actual synchronization service
+must use the HTTPS protocol, which means we can leave out this prefix.
diff --git a/src/api/cf/captcha-payment.txt b/src/api/cf/captcha-payment.txt
new file mode 100644
index 0000000..ecc065b
--- /dev/null
+++ b/src/api/cf/captcha-payment.txt
@@ -0,0 +1,116 @@
+Supporting DDoS blockers with Taler
+===================================
+
+Overview:
+
+  In many IP reputation systems, CAPTCHAS are used to separate humans from
+  bots, allowing humans to access resources while blocking automated
+  attackers.  However, especially complex modern Web sites require many
+  resources and thus can triger a large number of CAPTCHAS, limiting
+  usability.  The problem is compounded if users access the Web via
+  Tor or VPNs, as this means mechanisms to track users cannot be used to
+  reduce the number of CAPTCHAS.
+
+  We propose an alternative where we use Taler-style micropayments to
+  automatically pay for access to resources.  The micropayments would
+  be done in a provider-specific currency, effectively turning Taler
+  payments into anonymous credentials or tokens.  Tokens would be
+  provided by the provider in exchange for the user solving CAPTCHAS,
+  but instead of solving one CAPTCHA per request a user may be issued
+  thousands of tokens for one CAPTCHA, which could then be used across
+  multiple websites without creating anonymity/linkability issues.
+
+Rationale:
+
+  Reducing the use of CAPTCHA's improves usability for everybody, and
+  by (re)using Taler we limit the need for security audits for custom
+  solutions. Furthermore, it also becomes conceivable to move from
+  CAPTCHAS to actual payments or other mechanisms to hand out tokens
+  (i.e. researchers that legitimately need to perform automated
+  requests may apply for a token grant).
+
+Challenges:
+
+  To make this work, we need to address three issues:
+  1) Taler needs to add support for an 'auto-pay' flag that would be
+     associated with a currency. If the flag is present, the wallet
+     would not interactively ask the user to confirm the payment, but
+     just automatically pay (if funds are available; otherwise it
+     should redirect to the provider's "bank" where the user would
+     solve a CAPTCHA to obtain tokens).  This is relatively trivial
+     and necessary for usability.
+  2) Right now, the Wallet-Web site interaction uses JavaScript.  This
+     is not acceptable for some of the CAPTCHA-use case domains, as
+     Tor users may disable JavaScript and injecting Taler-specific
+     JavaScript into generic Web sites is messy.
+  3) The solution needs to work with embedded resources and POST requests,
+     where running a JavaScript interaction for each resource is both
+     too expensive and rather complicated.  Instead, a page should indicate
+     that all resources associated with a DOM require payment, and then
+     payment should automatically and efficiently be provided with each
+     request.
+
+Required changes to Taler:
+
+  We mainly need to make three changes:
+  1) Support for auto-pay (rather trivial), by tagging currencies, and
+     by redirecting to a "bank" page to withdraw tokens if funds are
+     insufficient.
+  2) In the 'withdraw' protocol, the bank should be able to specify the
+     payment system provider and tell the wallet to skip the interactive
+     selection/confirmation dialog (as there is only one provider and
+     thus no choice to be made). This change is also rather trivial.
+  3) Change Wallet to check for HTTP headers requesting payment for the
+     DOM, and then inject an HTTP header in all subsequent requests generated
+     by that page with the payment (i.e. signing the request's URL with
+     the coin/token).  This change is non-trivial, and may require
+     browser-specific solutions.
+
+Technical differences to captcha-plugin-draft.txt:
+  * both solutions use RSA blind signatures for privacy, my reading
+    of the draft is that 256-bits are proposed, while Taler leaves
+    the bit length variable (to the payment service provider).
+  * Taler uses Ed25519 for "tokens", while the draft proposes
+    random nonces as tokens.  Taler can thus spend tokens using
+    EdDSA signatures, while the draft uses encryption (of the
+    nonce/Token) with the server's key and a keyed HMAC.  I do not
+    attribute either design a significant performance advantage,
+    except with Taler the server could skip checking either signature
+    (to shard load if stressed), while the draft requires server-side
+    decryption to obtain the nonce.
+    Taler's use of an EdDSA signature is also more flexibile for other
+    applications, but in this particular context there is no
+    significant difference to the keyed HMAC with encrypted nonce.
+  * Instead of using the draft's scheme for withdrawing coins by
+    a magic HTML form attribute, Taler's bank API would be used,
+    where the bank (in this case the CAPTCHA-DDoS-protection provider)
+    signals to the wallet that a withdraw operation is being authorized
+    using a JavaScript signal. This is significantly more efficient,
+    as registering a signal handler is O(1) per page, while parsing
+    all DOMs to find a magic HTML form attribute is O(n) (where n is
+    the size of the DOM).
+
+
+Scalability:
+
+  Given that DDoS-protection has weaker requirements, it would be
+  trivial to use regional double-spending detection instead of global
+  double-spending detection.  Also, a custom exchange could use
+  probabilistic data structures to improve efficiency.
+  Alternatively, multiple currencies could be used; for this, the
+  HTTP header requiring auto-pay should simply specifiy the desired
+  currency, enabling further sharding of the load.
+
+Benefits of integrated solution with Taler:
+
+  * significant re-use of expertise, code, auditing effort and
+    protocol design
+  * provider-independent free software solution
+  * possibility to trivially "upgrade" to payment or data grants
+  * solution that is not Tor-specific, plugin should work for
+    various browsers
+  * 1 bit information leakage (is plugin present), instead of 2 bits
+    (if there are two separate plugins)
+  * Tor wants to solve CAPTCHA problem, Tor wants to support
+    anonymous payments.  This could solve both with 98%
+    shared code.
diff --git a/src/api/conf.py b/src/api/conf.py
new file mode 100644
index 0000000..6758983
--- /dev/null
+++ b/src/api/conf.py
@@ -0,0 +1,285 @@
+"""
+  This file is part of GNU TALER.
+  Copyright (C) 2014, 2015, 2016 GNUnet e.V. and INRIA
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Lesser General Public License as published by the Free 
Software
+  Foundation; either version 2.1, or (at your option) any later version.
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
details.
+  You should have received a copy of the GNU Lesser General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+
+  @author Florian Dold
+  @author Benedikt Muller
+  @author Sree Harsha Totakura
+  @author Marcello Stanisci
+"""
+# -*- coding: utf-8 -*-
+#
+# neuro documentation build configuration file, created by
+# sphinx-quickstart on Sat May 31 13:11:06 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
+import 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.3'
+
+sys.path.append(os.path.abspath('exts'))
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+    'tsref',
+    'sphinx.ext.todo',
+    'sphinx.ext.imgmath',
+    'httpdomain.httpdomain'
+]
+
+# 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'Taler'
+copyright = u'2014, 2015, 2016 Florian Dold, Benedikt Muller, Sree Harsha 
Totakura, Christian Grothoff, Marcello Stanisci (GPLv3+ or GFDL 1.3+)'
+
+# 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 = '0.4'
+# The full version, including alpha/beta/rc tags.
+release = '0.4.0'
+
+# 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 = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+#keep_warnings = False
+
+
+# -- 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']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#html_extra_path = []
+
+# 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 = False
+
+# 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 = 'neurodoc'
+
+
+# -- 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, or own class]).
+latex_documents = [
+  ('index', 'taler.tex', u'Taler Documentation',
+   u'F. Dold, B. Muller, S. H. Totakura, C. Grothoff',
+  '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', 'taler', u'GNU Taler Documentation',
+     [u'F. Dold, B. Muller, S. H. Totakura, C. Grothoff'],
+     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', 'taler', u'GNU Taler Documentation',
+   u'F. Dold, B. Muller, S. H. Totakura, C. Grothoff',
+   'neuro', 'One-Click Cash Payments.',
+   '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'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#texinfo_no_detailmenu = False
diff --git a/src/api/diagram.dot b/src/api/diagram.dot
new file mode 100644
index 0000000..1ddc6d2
--- /dev/null
+++ b/src/api/diagram.dot
@@ -0,0 +1,21 @@
+digraph g {
+# size="800,800";
+compound=true;
+concatenate=true;
+subgraph cluster_wallet {
+   style=filled;
+   color=lightgrey;
+   webex [label="wallet-webex"];
+   android [label="wallet-android"];
+   legacy [label="wallet-legacy"];
+   label="Wallets";
+}
+android -> merchant_frontend [label="buy", ltail=cluster_wallet];
+merchant_frontend -> merchant_backend [dir="both"];
+merchant_frontend [label="merchant (frontend)"];
+merchant_backend [label="merchant (backend)"];
+android -> exchange [label="withdraw", ltail=cluster_wallet, dir="both"];
+merchant_backend -> exchange [label="deposit"];
+android -> bank [label="select exchange", ltail=cluster_wallet];
+bank -> exchange [label="wire transfer", dir="both"];
+}
diff --git a/src/api/exts/httpdomain/__init__.py 
b/src/api/exts/httpdomain/__init__.py
new file mode 100644
index 0000000..b5a7dc2
--- /dev/null
+++ b/src/api/exts/httpdomain/__init__.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinxcontrib
+    ~~~~~~~~~~~~~
+
+    This package is a namespace package that contains all extensions
+    distributed in the ``sphinx-contrib`` distribution.
+
+    :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+__import__('pkg_resources').declare_namespace(__name__)
+
diff --git a/src/api/exts/httpdomain/autohttp/__init__.py 
b/src/api/exts/httpdomain/autohttp/__init__.py
new file mode 100644
index 0000000..95372d4
--- /dev/null
+++ b/src/api/exts/httpdomain/autohttp/__init__.py
@@ -0,0 +1,11 @@
+"""
+    sphinxcontrib.autohttp
+    ~~~~~~~~~~~~~~~~~~~~~~
+
+    The sphinx.ext.autodoc-style HTTP API reference builder
+    for sphinxcontrib.httpdomain.
+
+    :copyright: Copyright 2011 by Hong Minhee
+    :license: BSD, see LICENSE for details.
+
+"""
diff --git a/src/api/exts/httpdomain/autohttp/bottle.py 
b/src/api/exts/httpdomain/autohttp/bottle.py
new file mode 100644
index 0000000..d8c1859
--- /dev/null
+++ b/src/api/exts/httpdomain/autohttp/bottle.py
@@ -0,0 +1,114 @@
+"""
+    sphinxcontrib.autohttp.bottle
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    The sphinx.ext.autodoc-style HTTP API reference builder (from Bottle)
+    for sphinxcontrib.httpdomain.
+
+    :copyright: Copyright 2012 by Jameel Al-Aziz
+    :license: BSD, see LICENSE for details.
+
+"""
+
+import re
+import six
+
+from docutils import nodes
+from docutils.parsers.rst import directives
+from docutils.statemachine import ViewList
+
+from sphinx.util import force_decode
+from sphinx.util.compat import Directive
+from sphinx.util.nodes import nested_parse_with_titles
+from sphinx.util.docstrings import prepare_docstring
+from sphinx.pycode import ModuleAnalyzer
+
+from sphinxcontrib import httpdomain
+from sphinxcontrib.autohttp.common import http_directive, import_object
+
+
+def translate_bottle_rule(app, rule):
+    buf = six.StringIO()
+    if hasattr(app.router, "parse_rule"):
+        iterator = app.router.parse_rule(rule)  # bottle 0.11
+    else:
+        iterator = app.router._itertokens(rule)  # bottle 0.12
+    for name, filter, conf in iterator:
+        if filter:
+            buf.write('(')
+            buf.write(name)
+            if (filter != app.router.default_filter and filter != 'default')\
+                    or conf:
+                buf.write(':')
+                buf.write(filter)
+            if conf:
+                buf.write(':')
+                buf.write(conf)
+            buf.write(')')
+        else:
+            buf.write(name)
+    return buf.getvalue()
+
+
+def get_routes(app):
+    for route in app.routes:
+        path = translate_bottle_rule(app, route.rule)
+        yield route.method, path, route
+
+
+class AutobottleDirective(Directive):
+
+    has_content = True
+    required_arguments = 1
+    option_spec = {'endpoints': directives.unchanged,
+                   'undoc-endpoints': directives.unchanged,
+                   'include-empty-docstring': directives.unchanged}
+
+    @property
+    def endpoints(self):
+        endpoints = self.options.get('endpoints', None)
+        if not endpoints:
+            return None
+        return frozenset(re.split(r'\s*,\s*', endpoints))
+
+    @property
+    def undoc_endpoints(self):
+        undoc_endpoints = self.options.get('undoc-endpoints', None)
+        if not undoc_endpoints:
+            return frozenset()
+        return frozenset(re.split(r'\s*,\s*', undoc_endpoints))
+
+    def make_rst(self):
+        app = import_object(self.arguments[0])
+        for method, path, target in get_routes(app):
+            endpoint = target.name or target.callback.__name__
+            if self.endpoints and endpoint not in self.endpoints:
+                continue
+            if endpoint in self.undoc_endpoints:
+                continue
+            view = target.callback
+            docstring = view.__doc__ or ''
+            if not isinstance(docstring, six.text_type):
+                analyzer = ModuleAnalyzer.for_module(view.__module__)
+                docstring = force_decode(docstring, analyzer.encoding)
+            if not docstring and 'include-empty-docstring' not in self.options:
+                continue
+            docstring = prepare_docstring(docstring)
+            for line in http_directive(method, path, docstring):
+                yield line
+
+    def run(self):
+        node = nodes.section()
+        node.document = self.state.document
+        result = ViewList()
+        for line in self.make_rst():
+            result.append(line, '<autobottle>')
+        nested_parse_with_titles(self.state, result, node)
+        return node.children
+
+
+def setup(app):
+    if 'http' not in app.domains:
+        httpdomain.setup(app)
+    app.add_directive('autobottle', AutobottleDirective)
+
diff --git a/src/api/exts/httpdomain/autohttp/common.py 
b/src/api/exts/httpdomain/autohttp/common.py
new file mode 100644
index 0000000..199e297
--- /dev/null
+++ b/src/api/exts/httpdomain/autohttp/common.py
@@ -0,0 +1,36 @@
+"""
+    sphinxcontrib.autohttp.common
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    The common functions for web framework reflection.
+
+    :copyright: Copyright 2011 by Hong Minhee
+    :license: BSD, see LICENSE for details.
+
+"""
+import six
+from six.moves import builtins
+from six.moves import reduce
+
+def import_object(import_name):
+    module_name, expr = import_name.split(':', 1)
+    mod = __import__(module_name)
+    mod = reduce(getattr, module_name.split('.')[1:], mod)
+    globals = builtins
+    if not isinstance(globals, dict):
+        globals = globals.__dict__
+    return eval(expr, globals, mod.__dict__)
+
+
+def http_directive(method, path, content):
+    method = method.lower().strip()
+    if isinstance(content, six.string_types):
+        content = content.splitlines()
+    yield ''
+    paths = [path] if isinstance(path, six.string_types) else path
+    for path in paths:
+        yield '.. http:{method}:: {path}'.format(**locals())
+    yield ''
+    for line in content:
+        yield '   ' + line
+    yield ''
diff --git a/src/api/exts/httpdomain/autohttp/flask.py 
b/src/api/exts/httpdomain/autohttp/flask.py
new file mode 100644
index 0000000..4bd5232
--- /dev/null
+++ b/src/api/exts/httpdomain/autohttp/flask.py
@@ -0,0 +1,48 @@
+"""
+    sphinxcontrib.autohttp.flask
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    The sphinx.ext.autodoc-style HTTP API reference builder (from Flask)
+    for sphinxcontrib.httpdomain.
+
+    :copyright: Copyright 2011 by Hong Minhee
+    :license: BSD, see LICENSE for details.
+
+"""
+from __future__ import absolute_import
+
+import re
+import itertools
+import six
+
+from docutils import nodes
+from docutils.parsers.rst import directives
+from docutils.statemachine import ViewList
+
+from sphinx.util import force_decode
+from sphinx.util.compat import Directive
+from sphinx.util.nodes import nested_parse_with_titles
+from sphinx.util.docstrings import prepare_docstring
+from sphinx.pycode import ModuleAnalyzer
+
+from sphinxcontrib import httpdomain
+from sphinxcontrib.autohttp.common import http_directive, import_object
+
+from .flask_base import AutoflaskBase
+
+class AutoflaskDirective(AutoflaskBase):
+
+    def run(self):
+        node = nodes.section()
+        node.document = self.state.document
+        result = ViewList()
+        for line in self.make_rst():
+            result.append(line, '<autoflask>')
+        nested_parse_with_titles(self.state, result, node)
+        return node.children
+
+
+def setup(app):
+    if 'http' not in app.domains:
+        httpdomain.setup(app)
+    app.add_directive('autoflask', AutoflaskDirective)
diff --git a/src/api/exts/httpdomain/autohttp/flask_base.py 
b/src/api/exts/httpdomain/autohttp/flask_base.py
new file mode 100644
index 0000000..50454fe
--- /dev/null
+++ b/src/api/exts/httpdomain/autohttp/flask_base.py
@@ -0,0 +1,215 @@
+"""
+    sphinxcontrib.autohttp.flask
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    The sphinx.ext.autodoc-style HTTP API reference builder (from Flask)
+    for sphinxcontrib.httpdomain.
+
+    :copyright: Copyright 2011 by Hong Minhee
+    :license: BSD, see LICENSE for details.
+
+"""
+
+import re
+import itertools
+import six
+
+from docutils import nodes
+from docutils.parsers.rst import directives
+from docutils.statemachine import ViewList
+
+from sphinx.util import force_decode
+from sphinx.util.compat import Directive
+from sphinx.util.nodes import nested_parse_with_titles
+from sphinx.util.docstrings import prepare_docstring
+from sphinx.pycode import ModuleAnalyzer
+
+from sphinxcontrib import httpdomain
+from sphinxcontrib.autohttp.common import http_directive, import_object
+
+
+def translate_werkzeug_rule(rule):
+    from werkzeug.routing import parse_rule
+    buf = six.StringIO()
+    for conv, arg, var in parse_rule(rule):
+        if conv:
+            buf.write('(')
+            if conv != 'default':
+                buf.write(conv)
+                buf.write(':')
+            buf.write(var)
+            buf.write(')')
+        else:
+            buf.write(var)
+    return buf.getvalue()
+
+
+def get_routes(app, endpoint=None, order=None):
+    endpoints = []
+    for rule in app.url_map.iter_rules(endpoint):
+        url_with_endpoint = (
+            six.text_type(next(app.url_map.iter_rules(rule.endpoint))),
+            rule.endpoint
+        )
+        if url_with_endpoint not in endpoints:
+            endpoints.append(url_with_endpoint)
+    if order == 'path':
+        endpoints.sort()
+    endpoints = [e for _, e in endpoints]
+    for endpoint in endpoints:
+        methodrules = {}
+        for rule in app.url_map.iter_rules(endpoint):
+            methods = rule.methods.difference(['OPTIONS', 'HEAD'])
+            path = translate_werkzeug_rule(rule.rule)
+            for method in methods:
+                if method in methodrules:
+                    methodrules[method].append(path)
+                else:
+                    methodrules[method] = [path]
+        for method, paths in methodrules.items():
+            yield method, paths, endpoint
+
+
+def quickref_directive(method, path, content):
+    rcomp = re.compile("^\s*.. :quickref:\s*(?P<quick>.*)$")
+    method = method.lower().strip()
+    if isinstance(content, six.string_types):
+         content = content.splitlines()
+    description=""
+    name=""
+    ref = 
path.replace("<","(").replace(">",")").replace("/","-").replace(":","-")
+    for line in content:
+         qref = rcomp.match(line)
+         if qref:
+            quickref = qref.group("quick")
+            parts = quickref.split(";",1)
+            if len(parts)>1:
+                name = parts[0]
+                description= parts[1]
+            else:
+                description= quickref
+            break
+
+    row ={}
+    row['name'] = name
+    row['operation'] = '      - `%s %s <#%s-%s>`_' % (method.upper(), path, 
method.lower(), ref)
+    row['description'] = description
+
+    return row
+
+class AutoflaskBase(Directive):
+
+    has_content = True
+    required_arguments = 1
+    option_spec = {'endpoints': directives.unchanged,
+                   'blueprints': directives.unchanged,
+                   'modules': directives.unchanged,
+                   'order': directives.unchanged,
+                   'undoc-endpoints': directives.unchanged,
+                   'undoc-blueprints': directives.unchanged,
+                   'undoc-modules': directives.unchanged,
+                   'undoc-static': directives.unchanged,
+                   'include-empty-docstring': directives.unchanged}
+
+    @property
+    def endpoints(self):
+        endpoints = self.options.get('endpoints', None)
+        if not endpoints:
+            return None
+        return re.split(r'\s*,\s*', endpoints)
+
+    @property
+    def undoc_endpoints(self):
+        undoc_endpoints = self.options.get('undoc-endpoints', None)
+        if not undoc_endpoints:
+            return frozenset()
+        return frozenset(re.split(r'\s*,\s*', undoc_endpoints))
+
+    @property
+    def blueprints(self):
+        blueprints = self.options.get('blueprints', None)
+        if not blueprints:
+            return None
+        return frozenset(re.split(r'\s*,\s*', blueprints))
+
+    @property
+    def undoc_blueprints(self):
+        undoc_blueprints = self.options.get('undoc-blueprints', None)
+        if not undoc_blueprints:
+            return frozenset()
+        return frozenset(re.split(r'\s*,\s*', undoc_blueprints))
+
+    @property
+    def modules(self):
+        modules = self.options.get('modules', None)
+        if not modules:
+            return frozenset()
+        return frozenset(re.split(r'\s*,\s*', modules))
+
+    @property
+    def undoc_modules(self):
+        undoc_modules = self.options.get('undoc-modules', None)
+        if not undoc_modules:
+            return frozenset()
+        return frozenset(re.split(r'\s*,\s*', undoc_modules))
+
+    @property
+    def order(self):
+        order = self.options.get('order', None)
+        if order not in (None, 'path'):
+            raise ValueError('Invalid value for :order:')
+        return order
+
+    def make_rst(self, qref=False):
+        app = import_object(self.arguments[0])
+        if self.endpoints:
+            routes = itertools.chain(*[get_routes(app, endpoint, self.order)
+                    for endpoint in self.endpoints])
+        else:
+            routes = get_routes(app, order=self.order)
+        for method, paths, endpoint in routes:
+            try:
+                blueprint, _, endpoint_internal = endpoint.rpartition('.')
+                if self.blueprints and blueprint not in self.blueprints:
+                    continue
+                if blueprint in self.undoc_blueprints:
+                    continue
+            except ValueError:
+                pass  # endpoint is not within a blueprint
+
+            if endpoint in self.undoc_endpoints:
+                continue
+            try:
+                static_url_path = app.static_url_path # Flask 0.7 or higher
+            except AttributeError:
+                static_url_path = app.static_path # Flask 0.6 or under
+            if ('undoc-static' in self.options and endpoint == 'static' and
+                static_url_path + '/(path:filename)' in paths):
+                continue
+            view = app.view_functions[endpoint]
+
+            if self.modules and view.__module__ not in self.modules:
+                continue
+
+            if self.undoc_modules and view.__module__ in self.modules:
+                continue
+
+            docstring = view.__doc__ or ''
+            if hasattr(view, 'view_class'):
+                meth_func = getattr(view.view_class, method.lower(), None)
+                if meth_func and meth_func.__doc__:
+                    docstring = meth_func.__doc__
+            if not isinstance(docstring, six.text_type):
+                analyzer = ModuleAnalyzer.for_module(view.__module__)
+                docstring = force_decode(docstring, analyzer.encoding)
+
+            if not docstring and 'include-empty-docstring' not in self.options:
+                continue
+            docstring = prepare_docstring(docstring)
+            if qref == True:
+                for path in paths:
+                    row = quickref_directive(method, path, docstring)
+                    yield row
+            else:
+                for line in http_directive(method, paths, docstring):
+                    yield line
diff --git a/src/api/exts/httpdomain/autohttp/flaskqref.py 
b/src/api/exts/httpdomain/autohttp/flaskqref.py
new file mode 100644
index 0000000..c28bb15
--- /dev/null
+++ b/src/api/exts/httpdomain/autohttp/flaskqref.py
@@ -0,0 +1,80 @@
+"""
+    sphinxcontrib.autohttp.flaskqref
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    The sphinx.ext.autodoc-style HTTP API quick reference 
+    builder (from Flask)
+    for sphinxcontrib.httpdomain.
+
+    :copyright: Copyright 2011 by Hong Minhee
+    :license: BSD, see LICENSE for details.
+
+"""
+
+from docutils import nodes
+from docutils.statemachine import ViewList
+
+from sphinxcontrib import httpdomain
+from sphinx.util.nodes import nested_parse_with_titles
+
+from .flask import AutoflaskBase
+
+
+class QuickReferenceFlaskDirective(AutoflaskBase):
+
+
+    header = [ '',
+              '.. list-table::',
+              '    :widths: 20 45 35',
+              '    :header-rows: 1',
+              '',
+              '    * - Resource',
+              '      - Operation',
+              '      - Description'
+            ]
+
+    def run(self):
+        node = nodes.section()
+        node.document = self.state.document
+        result = ViewList()
+        for line in QuickReferenceFlaskDirective.header:
+            result.append(line, '<qrefflask>') 
+        table={}
+        table_sorted_names=[]
+        
+        for table_row in self.make_rst(qref=True):
+            name = table_row['name']
+            if table.get(name) is None:
+                table[name]=[]
+            table[name].append(table_row) 
+            if name not in table_sorted_names:
+                table_sorted_names.append(name)
+
+        table_sorted_names.sort()
+
+        for name in table_sorted_names:
+            # Keep table display clean by not repeating duplicate
+            # resource names and descriptions
+            display_name = name
+            previous_description=None
+            for row in table[name]:
+                result.append('    * - %s' % display_name, '<qrefflask>')
+                display_name =""
+                result.append(row['operation'], '<qrefflask>')
+                description = row['description']
+                if previous_description is not None and previous_description 
== description:
+                    description =""
+                else:
+                    previous_description = description
+
+                result.append('      - %s' % description,  '<qrefflask>')
+
+        result.append('', '<qrefflask>')
+        nested_parse_with_titles(self.state, result, node)
+        return node.children
+        
+def setup(app):
+    if 'http' not in app.domains:
+        httpdomain.setup(app)
+    app.add_directive('qrefflask', QuickReferenceFlaskDirective)
+
diff --git a/src/api/exts/httpdomain/autohttp/tornado.py 
b/src/api/exts/httpdomain/autohttp/tornado.py
new file mode 100644
index 0000000..9a514fe
--- /dev/null
+++ b/src/api/exts/httpdomain/autohttp/tornado.py
@@ -0,0 +1,128 @@
+"""
+    sphinxcontrib.autohttp.tornado
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    The sphinx.ext.autodoc-style HTTP API reference builder (from Tornado)
+    for sphinxcontrib.httpdomain.
+
+    :copyright: Copyright 2013 by Rodrigo Machado
+    :license: BSD, see LICENSE for details.
+
+"""
+
+import inspect
+import re
+import six
+
+from docutils import nodes
+from docutils.parsers.rst import directives
+from docutils.statemachine import ViewList
+
+from sphinx.util import force_decode
+from sphinx.util.compat import Directive
+from sphinx.util.nodes import nested_parse_with_titles
+from sphinx.util.docstrings import prepare_docstring
+from sphinx.pycode import ModuleAnalyzer
+
+from sphinxcontrib import httpdomain
+from sphinxcontrib.autohttp.common import http_directive, import_object
+
+
+def translate_tornado_rule(app, rule):
+    buf = six.StringIO()
+    for name, filter, conf in app.router.parse_rule(rule):
+        if filter:
+            buf.write('(')
+            buf.write(name)
+            if filter != app.router.default_filter or conf:
+                buf.write(':')
+                buf.write(filter)
+            if conf:
+                buf.write(':')
+                buf.write(conf)
+            buf.write(')')
+        else:
+            buf.write(name)
+    return buf.getvalue()
+
+
+def get_routes(app):
+    for spec in app.handlers[0][1]:
+        handler = spec.handler_class
+        doc_methods = list(handler.SUPPORTED_METHODS)
+        if 'HEAD' in doc_methods:
+            doc_methods.remove('HEAD')
+        if 'OPTIONS' in doc_methods:
+            doc_methods.remove('OPTIONS')
+
+        for method in doc_methods:
+            maybe_method = getattr(handler, method.lower(), None)
+            if (inspect.isfunction(maybe_method) or
+                    inspect.ismethod(maybe_method)):
+                yield method.lower(), spec.regex.pattern, handler
+
+
+def normalize_path(path):
+    if path.endswith('$'):
+        path = path[:-1]
+    return path
+
+
+class AutoTornadoDirective(Directive):
+
+    has_content = True
+    required_arguments = 1
+    option_spec = {'endpoints': directives.unchanged,
+                   'undoc-endpoints': directives.unchanged,
+                   'include-empty-docstring': directives.unchanged}
+
+    @property
+    def endpoints(self):
+        endpoints = self.options.get('endpoints', None)
+        if not endpoints:
+            return None
+        return frozenset(re.split(r'\s*,\s*', endpoints))
+
+    @property
+    def undoc_endpoints(self):
+        undoc_endpoints = self.options.get('undoc-endpoints', None)
+        if not undoc_endpoints:
+            return frozenset()
+        return frozenset(re.split(r'\s*,\s*', undoc_endpoints))
+
+    def make_rst(self):
+        app = import_object(self.arguments[0])
+        for method, path, handler in get_routes(app):
+            class_name = handler.__name__
+            method_name = getattr(handler, method).__name__
+            endpoint = '.'.join((class_name, method_name))
+
+            if self.endpoints and endpoint not in self.endpoints:
+                continue
+            if endpoint in self.undoc_endpoints:
+                continue
+
+            docstring = getattr(handler, method).__doc__ or ''
+            #if not isinstance(docstring, unicode):
+            #    analyzer = ModuleAnalyzer.for_module(view.__module__)
+            #    docstring = force_decode(docstring, analyzer.encoding)
+            if not docstring and 'include-empty-docstring' not in self.options:
+                continue
+            docstring = prepare_docstring(docstring)
+            for line in http_directive(method, normalize_path(path), 
docstring):
+                yield line
+
+    def run(self):
+        node = nodes.section()
+        node.document = self.state.document
+        result = ViewList()
+        for line in self.make_rst():
+            result.append(line, '<autotornado>')
+        nested_parse_with_titles(self.state, result, node)
+        return node.children
+
+
+def setup(app):
+    if 'http' not in app.domains:
+        httpdomain.setup(app)
+    app.add_directive('autotornado', AutoTornadoDirective)
diff --git a/src/api/exts/httpdomain/httpdomain.py 
b/src/api/exts/httpdomain/httpdomain.py
new file mode 100644
index 0000000..a5e3471
--- /dev/null
+++ b/src/api/exts/httpdomain/httpdomain.py
@@ -0,0 +1,771 @@
+"""
+    sphinxcontrib.httpdomain
+    ~~~~~~~~~~~~~~~~~~~~~~~~
+
+    The HTTP domain for documenting RESTful HTTP APIs.
+
+    :copyright: Copyright 2011 by Hong Minhee
+    :license: BSD, see LICENSE for details.
+
+"""
+
+import re
+
+from docutils import nodes
+
+from pygments.lexer import RegexLexer, bygroups
+from pygments.lexers import get_lexer_by_name
+from pygments.token import Literal, Text, Operator, Keyword, Name, Number
+from pygments.util import ClassNotFound
+
+from sphinx import addnodes
+from sphinx.roles import XRefRole
+from sphinx.domains import Domain, ObjType, Index
+from sphinx.directives import ObjectDescription, directives
+from sphinx.util.nodes import make_refnode
+from sphinx.util.docfields import GroupedField, TypedField
+
+# The env.get_doctree() lookup results in a pickle.load() call which is
+# expensive enough to dominate the runtime entirely when the number of 
endpoints
+# and references is large enough. The doctrees are generated during the read-
+# phase and we can cache their lookup during the write-phase significantly
+# improving performance.
+# Currently sphinxcontrib-httpdomain does not declare to support parallel read
+# support (parallel_read_safe is the default False) so we can simply use a
+# module global to hold the cache.
+_doctree_cache = {}
+
+
+class DocRef(object):
+    """Represents a reference to an abstract specification."""
+
+    def __init__(self, base_url, anchor, section):
+        self.base_url = base_url
+        self.anchor = anchor
+        self.section = section
+
+    def __repr__(self):
+        """Returns the URL onto related specification section for the related
+        object."""
+        return '{0}#{1}{2}'.format(self.base_url, self.anchor, self.section)
+
+
+class RFC2616Ref(DocRef):
+    """Represents a reference to RFC2616.
+    In 2014, RFC2616 was replaced by multiple RFCs (7230-7237)."""
+
+    def __init__(self, section):
+        url = 'http://www.w3.org/Protocols/rfc2616/rfc2616-sec{0:d}.html'
+        url = url.format(int(section))
+        super(RFC2616Ref, self).__init__(url, 'sec', section)
+
+
+class IETFRef(DocRef):
+    """Represents a reference to the specific IETF RFC."""
+
+    def __init__(self, rfc, section):
+        url = 'https://tools.ietf.org/html/rfc{0:d}'.format(rfc)
+        super(IETFRef, self).__init__(url, 'section-', section)
+
+
+class EventSourceRef(DocRef):
+
+    def __init__(self, section):
+        url = 'http://www.w3.org/TR/eventsource/'
+        super(EventSourceRef, self).__init__(url, section, '')
+
+
+class CORSRef(DocRef):
+    """Represents a reference to W3 Cross-Origin Resource Sharing 
recommendation."""
+
+    def __init__(self, name, type):
+        url = 'http://www.w3.org/TR/cors/'
+        super(CORSRef, self).__init__(url, name, '-' + type)
+
+
+#: Mapping from lowercase HTTP method name to :class:`DocRef` object which
+#: maintains the URL which points to the section of the RFC which defines that
+#: HTTP method.
+METHOD_REFS = {
+    'patch': IETFRef(5789, 2),
+    'options': IETFRef(7231, '4.3.7'),
+    'get': IETFRef(7231, '4.3.1'),
+    'head': IETFRef(7231, '4.3.2'),
+    'post': IETFRef(7231, '4.3.3'),
+    'put': IETFRef(7231, '4.3.4'),
+    'delete': IETFRef(7231, '4.3.5'),
+    'trace': IETFRef(7231, '4.3.8'),
+    'connect': IETFRef(7231, '4.3.6'),
+    'copy': IETFRef(2518, 8.8),
+    'any': ''
+}
+
+
+#: Mapping from HTTP header name to :class:`DocRef` object which
+#: maintains the URL which points to the related section of the RFC.
+HEADER_REFS = {
+    'Accept': IETFRef(7231, '5.3.2'),
+    'Accept-Charset': IETFRef(7231, '5.3.3'),
+    'Accept-Encoding': IETFRef(7231, '5.3.4'),
+    'Accept-Language': IETFRef(7231, '5.3.5'),
+    'Accept-Ranges': IETFRef(7233, 2.3),
+    'Age': IETFRef(7234, 5.1),
+    'Allow': IETFRef(7231, '7.4.1'),
+    'Authorization': IETFRef(7235, 4.2),
+    'Cache-Control': IETFRef(7234, 5.2),
+    'Connection': IETFRef(7230, 6.1),
+    'Content-Encoding': IETFRef(7231, '3.1.2.2'),
+    'Content-Language': IETFRef(7231, '3.1.3.2'),
+    'Content-Length': IETFRef(7230, '3.3.2'),
+    'Content-Location': IETFRef(7231, '3.1.4.2'),
+    'Content-MD5': RFC2616Ref(14.15), # removed
+    'Content-Range': IETFRef(7233, 4.2),
+    'Content-Type': IETFRef(7231, '3.1.1.5'),
+    'Cookie': IETFRef(2109, '4.3.4'), # also RFC6265 section 5.4
+    'Date': IETFRef(7231, '7.1.1.2'),
+    'Destination': IETFRef(2518, 9.3),
+    'ETag': IETFRef(7232, 2.3),
+    'Expect': IETFRef(7231, '5.1.1'),
+    'Expires': IETFRef(7234, 5.3),
+    'From': IETFRef(7231, '5.5.2'),
+    'Host': IETFRef(7230, 5.4),
+    'If-Match': IETFRef(7232, 3.1),
+    'If-Modified-Since': IETFRef(7232, 3.3),
+    'If-None-Match': IETFRef(7232, 3.2),
+    'If-Range': IETFRef(7233, 3.2),
+    'If-Unmodified-Since': IETFRef(7232, 3.4),
+    'Last-Event-ID': EventSourceRef('last-event-id'),
+    'Last-Modified': IETFRef(7232, 2.2),
+    'Link': IETFRef(5988, '5'),
+    'Location': IETFRef(7231, '7.1.2'),
+    'Max-Forwards': IETFRef(7231, '5.1.2'),
+    'Pragma': IETFRef(7234, 5.4),
+    'Proxy-Authenticate': IETFRef(7235, 4.3),
+    'Proxy-Authorization': IETFRef(7235, 4.4),
+    'Range': IETFRef(7233, 3.1),
+    'Referer': IETFRef(7231, '5.5.2'),
+    'Retry-After': IETFRef(7231, '7.1.3'),
+    'Server': IETFRef(7231, '7.4.2'),
+    'Set-Cookie': IETFRef(2109, '4.2.2'),
+    'TE': IETFRef(7230, 4.3),
+    'Trailer': IETFRef(7230, 4.4),
+    'Transfer-Encoding': IETFRef(7230, '3.3.1'),
+    'Upgrade': IETFRef(7230, 6.7),
+    'User-Agent': IETFRef(7231, '5.5.3'),
+    'Vary': IETFRef(7231, '7.1.4'),
+    'Via': IETFRef(7230, '5.7.1'),
+    'Warning': IETFRef(7234, 5.5),
+    'WWW-Authenticate': IETFRef(7235, 4.1),
+    'Access-Control-Allow-Origin': CORSRef('access-control-allow-origin',
+                                           'response-header'),
+    'Access-Control-Allow-Credentials': 
CORSRef('access-control-allow-credentials',
+                                                'response-header'),
+    'Access-Control-Expose-Headers': CORSRef('access-control-expose-headers',
+                                             'response-header'),
+    'Access-Control-Max-Age': CORSRef('access-control-max-age',
+                                      'response-header'),
+    'Access-Control-Allow-Methods': CORSRef('access-control-allow-methods',
+                                            'response-header'),
+    'Access-Control-Allow-Headers': CORSRef('access-control-allow-headers',
+                                            'response-header'),
+    'Origin': CORSRef('origin', 'request-header'),
+    'Access-Control-Request-Method': CORSRef('access-control-request-method',
+                                             'response-header'),
+    'Access-Control-Request-Headers': CORSRef('access-control-request-headers',
+                                              'response-header'),
+}
+
+
+HTTP_STATUS_CODES = {
+    100: 'Continue',
+    101: 'Switching Protocols',
+    102: 'Processing',
+    200: 'OK',
+    201: 'Created',
+    202: 'Accepted',
+    203: 'Non Authoritative Information',
+    204: 'No Content',
+    205: 'Reset Content',
+    206: 'Partial Content',
+    207: 'Multi Status',
+    226: 'IM Used',              # see RFC 3229
+    300: 'Multiple Choices',
+    301: 'Moved Permanently',
+    302: 'Found',
+    303: 'See Other',
+    304: 'Not Modified',
+    305: 'Use Proxy',
+    307: 'Temporary Redirect',
+    400: 'Bad Request',
+    401: 'Unauthorized',
+    402: 'Payment Required',     # unused
+    403: 'Forbidden',
+    404: 'Not Found',
+    405: 'Method Not Allowed',
+    406: 'Not Acceptable',
+    407: 'Proxy Authentication Required',
+    408: 'Request Timeout',
+    409: 'Conflict',
+    410: 'Gone',
+    411: 'Length Required',
+    412: 'Precondition Failed',
+    413: 'Request Entity Too Large',
+    414: 'Request URI Too Long',
+    415: 'Unsupported Media Type',
+    416: 'Requested Range Not Satisfiable',
+    417: 'Expectation Failed',
+    418: "I'm a teapot",        # see RFC 2324
+    422: 'Unprocessable Entity',
+    423: 'Locked',
+    424: 'Failed Dependency',
+    426: 'Upgrade Required',
+    429: 'Too Many Requests',
+    449: 'Retry With',           # proprietary MS extension
+    451: 'Unavailable For Legal Reasons',
+    500: 'Internal Server Error',
+    501: 'Not Implemented',
+    502: 'Bad Gateway',
+    503: 'Service Unavailable',
+    504: 'Gateway Timeout',
+    505: 'HTTP Version Not Supported',
+    507: 'Insufficient Storage',
+    510: 'Not Extended'
+}
+
+WEBDAV_STATUS_CODES = [207, 422, 423, 424, 507]
+
+http_sig_param_re = re.compile(r'\((?:(?P<type>[^:)]+):)?(?P<name>[\w_]+)\)',
+                               re.VERBOSE)
+
+
+def sort_by_method(entries):
+    def cmp(item):
+        order = ['HEAD', 'GET', 'POST', 'PUT', 'DELETE', 'PATCH',
+                 'OPTIONS', 'TRACE', 'CONNECT', 'COPY', 'ANY']
+        method = item[0].split(' ', 1)[0]
+        if method in order:
+            return order.index(method)
+        return 100
+    return sorted(entries, key=cmp)
+
+
+def http_resource_anchor(method, path):
+    path = re.sub(r'[{}]', '', re.sub(r'[<>:/]', '-', path))
+    return method.lower() + '-' + path
+
+
+class HTTPResource(ObjectDescription):
+
+    doc_field_types = [
+        TypedField('parameter', label='Parameters',
+                   names=('param', 'parameter', 'arg', 'argument'),
+                   typerolename='obj', typenames=('paramtype', 'type')),
+        TypedField('jsonparameter', label='JSON Parameters',
+                   names=('jsonparameter', 'jsonparam', 'json'),
+                   typerolename='obj', typenames=('jsonparamtype', 
'jsontype')),
+        TypedField('requestjsonobject', label='Request JSON Object',
+                   names=('reqjsonobj', 'reqjson', '<jsonobj', '<json'),
+                   typerolename='obj', typenames=('reqjsonobj', '<jsonobj')),
+        TypedField('requestjsonarray', label='Request JSON Array of Objects',
+                   names=('reqjsonarr', '<jsonarr'),
+                   typerolename='obj',
+                   typenames=('reqjsonarrtype', '<jsonarrtype')),
+        TypedField('responsejsonobject', label='Response JSON Object',
+                   names=('resjsonobj', 'resjson', '>jsonobj', '>json'),
+                   typerolename='obj', typenames=('resjsonobj', '>jsonobj')),
+        TypedField('responsejsonarray', label='Response JSON Array of Objects',
+                   names=('resjsonarr', '>jsonarr'),
+                   typerolename='obj',
+                   typenames=('resjsonarrtype', '>jsonarrtype')),
+        TypedField('queryparameter', label='Query Parameters',
+                   names=('queryparameter', 'queryparam', 'qparam', 'query'),
+                   typerolename='obj',
+                   typenames=('queryparamtype', 'querytype', 'qtype')),
+        GroupedField('formparameter', label='Form Parameters',
+                     names=('formparameter', 'formparam', 'fparam', 'form')),
+        GroupedField('requestheader', label='Request Headers',
+                     rolename='header',
+                     names=('<header', 'reqheader', 'requestheader')),
+        GroupedField('responseheader', label='Response Headers',
+                     rolename='header',
+                     names=('>header', 'resheader', 'responseheader')),
+        GroupedField('statuscode', label='Status Codes',
+                     rolename='statuscode',
+                     names=('statuscode', 'status', 'code'))
+    ]
+
+    option_spec = {
+        'deprecated': directives.flag,
+        'noindex': directives.flag,
+        'synopsis': lambda x: x,
+    }
+
+    method = NotImplemented
+
+    def handle_signature(self, sig, signode):
+        method = self.method.upper() + ' '
+        signode += addnodes.desc_name(method, method)
+        offset = 0
+        path = None
+        for match in http_sig_param_re.finditer(sig):
+            path = sig[offset:match.start()]
+            signode += addnodes.desc_name(path, path)
+            params = addnodes.desc_parameterlist()
+            typ = match.group('type')
+            if typ:
+                typ += ': '
+                params += addnodes.desc_annotation(typ, typ)
+            name = match.group('name')
+            params += addnodes.desc_parameter(name, name)
+            signode += params
+            offset = match.end()
+        if offset < len(sig):
+            path = sig[offset:len(sig)]
+            signode += addnodes.desc_name(path, path)
+        assert path is not None, 'no matches for sig: %s' % sig
+        fullname = self.method.upper() + ' ' + path
+        signode['method'] = self.method
+        signode['path'] = sig
+        signode['fullname'] = fullname
+        return (fullname, self.method, sig)
+
+    def needs_arglist(self):
+        return False
+
+    def add_target_and_index(self, name_cls, sig, signode):
+        signode['ids'].append(http_resource_anchor(*name_cls[1:]))
+        if 'noindex' not in self.options:
+            self.env.domaindata['http'][self.method][sig] = (
+                self.env.docname,
+                self.options.get('synopsis', ''),
+                'deprecated' in self.options)
+
+    def get_index_text(self, modname, name):
+        return ''
+
+
+class HTTPOptions(HTTPResource):
+
+    method = 'options'
+
+
+class HTTPHead(HTTPResource):
+
+    method = 'head'
+
+
+class HTTPPatch(HTTPResource):
+
+    method = 'patch'
+
+
+class HTTPPost(HTTPResource):
+
+    method = 'post'
+
+
+class HTTPGet(HTTPResource):
+
+    method = 'get'
+
+
+class HTTPPut(HTTPResource):
+
+    method = 'put'
+
+
+class HTTPDelete(HTTPResource):
+
+    method = 'delete'
+
+
+class HTTPTrace(HTTPResource):
+
+    method = 'trace'
+
+
+class HTTPConnect(HTTPResource):
+
+    method = 'connect'
+
+
+class HTTPCopy(HTTPResource):
+
+    method = 'copy'
+
+
+class HTTPAny(HTTPResource):
+
+    method = 'any'
+
+
+class HTTPXRefRole(XRefRole):
+
+    def __init__(self, method, **kwargs):
+        XRefRole.__init__(self, **kwargs)
+        self.method = method
+
+    def process_link(self, env, refnode, has_explicit_title, title, target):
+        if not has_explicit_title:
+            title = self.method.upper() + ' ' + title
+        return title, target
+
+
+class HTTPXRefMethodRole(XRefRole):
+
+    def result_nodes(self, document, env, node, is_ref):
+        method = node[0][0].lower()
+        rawsource = node[0].rawsource
+        config = env.domains['http'].env.config
+        if method not in METHOD_REFS:
+            if not config['http_strict_mode']:
+                return [nodes.emphasis(method, method)], []
+            reporter = document.reporter
+            msg = reporter.error('%s is not valid HTTP method' % method,
+                                 line=node.line)
+            prb = nodes.problematic(method, method)
+            return [prb], [msg]
+        url = str(METHOD_REFS[method])
+        if not url:
+            return [nodes.emphasis(method, method)], []
+        node = nodes.reference(rawsource, method.upper(), refuri=url)
+        return [node], []
+
+
+class HTTPXRefStatusRole(XRefRole):
+
+    def result_nodes(self, document, env, node, is_ref):
+        def get_code_status(text):
+            if text.isdigit():
+                code = int(text)
+                return code, HTTP_STATUS_CODES.get(code)
+            else:
+                try:
+                    code, status = re.split(r'\s', text.strip(), 1)
+                    code = int(code)
+                except ValueError:
+                    return None, None
+                known_status = HTTP_STATUS_CODES.get(code)
+                if known_status is None:
+                    return code, None
+                elif known_status.lower() != status.lower():
+                    return code, None
+                else:
+                    return code, status
+
+        def report_unknown_code():
+            if not config['http_strict_mode']:
+                return [nodes.emphasis(text, text)], []
+            reporter = document.reporter
+            msg = reporter.error('%d is unknown HTTP status code' % code,
+                                 line=node.line)
+            prb = nodes.problematic(text, text)
+            return [prb], [msg]
+
+        def report_invalid_code():
+            if not config['http_strict_mode']:
+                return [nodes.emphasis(text, text)], []
+            reporter = document.reporter
+            msg = reporter.error(
+                'HTTP status code must be an integer (e.g. `200`) or '
+                'start with an integer (e.g. `200 OK`); %r is invalid' %
+                text,
+                line=node.line
+            )
+            prb = nodes.problematic(text, text)
+            return [prb], [msg]
+
+        text = node[0][0]
+        rawsource = node[0].rawsource
+        config = env.domains['http'].env.config
+
+        code, status = get_code_status(text)
+        if code is None:
+            return report_invalid_code()
+        elif status is None:
+            return report_unknown_code()
+        elif code == 226:
+            url = 'http://www.ietf.org/rfc/rfc3229.txt'
+        elif code == 418:
+            url = 'http://www.ietf.org/rfc/rfc2324.txt'
+        elif code == 429:
+            url = 'http://tools.ietf.org/html/rfc6585#section-4'
+        elif code == 449:
+            url = 
'http://msdn.microsoft.com/en-us/library/dd891478(v=prot.10).aspx'
+        elif code == 451:
+            url = 'http://www.ietf.org/rfc/rfc7725.txt'
+        elif code in WEBDAV_STATUS_CODES:
+            url = 'http://tools.ietf.org/html/rfc4918#section-11.%d' % 
(WEBDAV_STATUS_CODES.index(code) + 1)
+        elif code in HTTP_STATUS_CODES:
+            url = 'http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html' \
+                  '#sec10.' + ('%d.%d' % (code // 100, 1 + code % 100))
+        else:
+            url = ''
+        node = nodes.reference(rawsource, '%d %s' % (code, status), refuri=url)
+        return [node], []
+
+
+class HTTPXRefHeaderRole(XRefRole):
+
+    def result_nodes(self, document, env, node, is_ref):
+        header = node[0][0]
+        rawsource = node[0].rawsource
+        if header not in HEADER_REFS:
+            _header = '-'.join(map(lambda i: i.title(), header.split('-')))
+            if _header not in HEADER_REFS:
+                return [nodes.emphasis(header, header)], []
+        url = str(HEADER_REFS[header])
+        node = nodes.reference(rawsource, header, refuri=url)
+        return [node], []
+
+
+class HTTPIndex(Index):
+
+    name = 'routingtable'
+    localname = 'HTTP Routing Table'
+    shortname = 'routing table'
+
+    def __init__(self, *args, **kwargs):
+        super(HTTPIndex, self).__init__(*args, **kwargs)
+
+        self.ignore = [
+            [l for l in x.split('/') if l]
+            for x in self.domain.env.config['http_index_ignore_prefixes']]
+        self.ignore.sort(reverse=True)
+
+        # During HTML generation these values pick from class,
+        # not from instance so we have a little hack the system
+        cls = self.__class__
+        cls.shortname = self.domain.env.config['http_index_shortname']
+        cls.localname = self.domain.env.config['http_index_localname']
+
+    def grouping_prefix(self, path):
+        letters = [x for x in path.split('/') if x]
+        for prefix in self.ignore:
+            if letters[:len(prefix)] == prefix:
+                return '/' + '/'.join(letters[:len(prefix) + 1])
+        return '/%s' % (letters[0] if letters else '',)
+
+    def generate(self, docnames=None):
+        content = {}
+        items = ((method, path, info)
+                 for method, routes in self.domain.routes.items()
+                 for path, info in routes.items())
+        items = sorted(items, key=lambda item: item[1])
+        for method, path, info in items:
+            entries = content.setdefault(self.grouping_prefix(path), [])
+            entries.append([
+                method.upper() + ' ' + path, 0, info[0],
+                http_resource_anchor(method, path),
+                '', 'Deprecated' if info[2] else '', info[1]
+            ])
+        items = sorted(
+            (path, sort_by_method(entries))
+            for path, entries in content.items()
+        )
+        return (items, True)
+
+
+class HTTPDomain(Domain):
+    """HTTP domain."""
+
+    name = 'http'
+    label = 'HTTP'
+
+    object_types = {
+        'options': ObjType('options', 'options', 'obj'),
+        'head': ObjType('head', 'head', 'obj'),
+        'post': ObjType('post', 'post', 'obj'),
+        'get': ObjType('get', 'get', 'obj'),
+        'put': ObjType('put', 'put', 'obj'),
+        'patch': ObjType('patch', 'patch', 'obj'),
+        'delete': ObjType('delete', 'delete', 'obj'),
+        'trace': ObjType('trace', 'trace', 'obj'),
+        'connect': ObjType('connect', 'connect', 'obj'),
+        'copy': ObjType('copy', 'copy', 'obj'),
+        'any': ObjType('any', 'any', 'obj')
+    }
+
+    directives = {
+        'options': HTTPOptions,
+        'head': HTTPHead,
+        'post': HTTPPost,
+        'get': HTTPGet,
+        'put': HTTPPut,
+        'patch': HTTPPatch,
+        'delete': HTTPDelete,
+        'trace': HTTPTrace,
+        'connect': HTTPConnect,
+        'copy': HTTPCopy,
+        'any': HTTPAny
+    }
+
+    roles = {
+        'options': HTTPXRefRole('options'),
+        'head': HTTPXRefRole('head'),
+        'post': HTTPXRefRole('post'),
+        'get': HTTPXRefRole('get'),
+        'put': HTTPXRefRole('put'),
+        'patch': HTTPXRefRole('patch'),
+        'delete': HTTPXRefRole('delete'),
+        'trace': HTTPXRefRole('trace'),
+        'connect': HTTPXRefRole('connect'),
+        'copy': HTTPXRefRole('copy'),
+        'any': HTTPXRefRole('any'),
+        'statuscode': HTTPXRefStatusRole(),
+        'method': HTTPXRefMethodRole(),
+        'header': HTTPXRefHeaderRole()
+    }
+
+    initial_data = {
+        'options': {},  # path: (docname, synopsis)
+        'head': {},
+        'post': {},
+        'get': {},
+        'put': {},
+        'patch': {},
+        'delete': {},
+        'trace': {},
+        'connect': {},
+        'copy': {},
+        'any': {}
+    }
+
+    indices = [HTTPIndex]
+
+    @property
+    def routes(self):
+        return dict((key, self.data[key]) for key in self.object_types)
+
+    def clear_doc(self, docname):
+        for typ, routes in self.routes.items():
+            for path, info in list(routes.items()):
+                if info[0] == docname:
+                    del routes[path]
+
+    def resolve_xref(self, env, fromdocname, builder, typ, target,
+                     node, contnode):
+        try:
+            info = self.data[str(typ)][target]
+        except KeyError:
+            text = contnode.rawsource
+            role = self.roles.get(typ)
+            if role is None:
+                return None
+
+            if fromdocname not in _doctree_cache:
+                _doctree_cache[fromdocname] = env.get_doctree(fromdocname)
+            doctree = _doctree_cache[fromdocname]
+
+            resnode = role.result_nodes(doctree, env, node, None)[0][0]
+            if isinstance(resnode, addnodes.pending_xref):
+                text = node[0][0]
+                reporter = doctree.reporter
+                reporter.warning('Cannot resolve reference to %r' % text,
+                                 line=node.line)
+                return None
+            return resnode
+        else:
+            anchor = http_resource_anchor(typ, target)
+            title = typ.upper() + ' ' + target
+            return make_refnode(builder, fromdocname, info[0], anchor,
+                                contnode, title)
+
+    def resolve_any_xref(self, env, fromdocname, builder, target, node, 
contnode):
+        """Resolve the pending_xref *node* with the given *target*.
+
+        The reference comes from an "any" or similar role, which means that 
Sphinx
+        don't know the type.
+
+        For now sphinxcontrib-httpdomain doesn't resolve any xref nodes.
+
+        :return:
+           list of tuples ``('domain:role', newnode)``, where ``'domain:role'``
+           is the name of a role that could have created the same reference,
+        """
+        return []
+
+    def get_objects(self):
+        for method, routes in self.routes.items():
+            for path, info in routes.items():
+                anchor = http_resource_anchor(method, path)
+                yield (path, path, method, info[0], anchor, 1)
+
+
+class HTTPLexer(RegexLexer):
+    """Lexer for HTTP sessions."""
+
+    name = 'HTTP'
+    aliases = ['http']
+
+    flags = re.DOTALL
+
+    def header_callback(self, match):
+        if match.group(1).lower() == 'content-type':
+            content_type = match.group(5).strip()
+            if ';' in content_type:
+                content_type = content_type[:content_type.find(';')].strip()
+            self.content_type = content_type
+        yield match.start(1), Name.Attribute, match.group(1)
+        yield match.start(2), Text, match.group(2)
+        yield match.start(3), Operator, match.group(3)
+        yield match.start(4), Text, match.group(4)
+        yield match.start(5), Literal, match.group(5)
+        yield match.start(6), Text, match.group(6)
+
+    def continuous_header_callback(self, match):
+        yield match.start(1), Text, match.group(1)
+        yield match.start(2), Literal, match.group(2)
+        yield match.start(3), Text, match.group(3)
+
+    def content_callback(self, match):
+        content_type = getattr(self, 'content_type', None)
+        content = match.group()
+        offset = match.start()
+        if content_type:
+            from pygments.lexers import get_lexer_for_mimetype
+            try:
+                lexer = get_lexer_for_mimetype(content_type)
+            except ClassNotFound:
+                pass
+            else:
+                for idx, token, value in lexer.get_tokens_unprocessed(content):
+                    yield offset + idx, token, value
+                return
+        yield offset, Text, content
+
+    tokens = {
+        'root': [
+            (r'(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS|TRACE|COPY)( +)([^ ]+)( 
+)'
+             r'(HTTPS?)(/)(1\.[01])(\r?\n|$)',
+             bygroups(Name.Function, Text, Name.Namespace, Text,
+                      Keyword.Reserved, Operator, Number, Text),
+             'headers'),
+            (r'(HTTPS?)(/)(1\.[01])( +)(\d{3})( +)([^\r\n]+)(\r?\n|$)',
+             bygroups(Keyword.Reserved, Operator, Number, Text, Number,
+                      Text, Name.Exception, Text),
+             'headers'),
+        ],
+        'headers': [
+            (r'([^\s:]+)( *)(:)( *)([^\r\n]+)(\r?\n|$)', header_callback),
+            (r'([\t ]+)([^\r\n]+)(\r?\n|$)', continuous_header_callback),
+            (r'\r?\n', Text, 'content')
+        ],
+        'content': [
+            (r'.+', content_callback)
+        ]
+    }
+
+
+def setup(app):
+    app.add_domain(HTTPDomain)
+
+    try:
+        get_lexer_by_name('http')
+    except ClassNotFound:
+        app.add_lexer('http', HTTPLexer())
+    app.add_config_value('http_index_ignore_prefixes', [], None)
+    app.add_config_value('http_index_shortname', 'routing table', True)
+    app.add_config_value('http_index_localname', 'HTTP Routing Table', True)
+    app.add_config_value('http_strict_mode', True, None)
+    app.add_config_value('http_headers_ignore_prefixes', ['X-'], None)
diff --git a/src/api/exts/tslex.py b/src/api/exts/tslex.py
new file mode 100644
index 0000000..2be6f29
--- /dev/null
+++ b/src/api/exts/tslex.py
@@ -0,0 +1,88 @@
+from pygments.token import *
+from pygments.lexer import RegexLexer, ExtendedRegexLexer, bygroups, using, \
+     include, this
+import re
+
+class BetterTypeScriptLexer(RegexLexer):
+    """
+    For `TypeScript <https://www.typescriptlang.org/>`_ source code.
+    """
+
+    name = 'TypeScript'
+    aliases = ['ts']
+    filenames = ['*.ts']
+    mimetypes = ['text/x-typescript']
+
+    flags = re.DOTALL
+    tokens = {
+        'commentsandwhitespace': [
+            (r'\s+', Text),
+            (r'<!--', Comment),
+            (r'//.*?\n', Comment.Single),
+            (r'/\*.*?\*/', Comment.Multiline)
+        ],
+        'slashstartsregex': [
+            include('commentsandwhitespace'),
+            (r'/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/'
+             r'([gim]+\b|\B)', String.Regex, '#pop'),
+            (r'(?=/)', Text, ('#pop', 'badregex')),
+            (r'', Text, '#pop')
+        ],
+        'badregex': [
+            (r'\n', Text, '#pop')
+        ],
+        'typeexp': [
+            (r'[a-zA-Z]+', Keyword.Type),
+            (r'\s+', Text),
+            (r'[|]', Text),
+            (r'\n', Text, "#pop"),
+            (r';', Text, "#pop"),
+            (r'', Text, "#pop"),
+        ],
+        'root': [
+            (r'^(?=\s|/|<!--)', Text, 'slashstartsregex'),
+            include('commentsandwhitespace'),
+            (r'\+\+|--|~|&&|\?|:|\|\||\\(?=\n)|'
+             r'(<<|>>>?|==?|!=?|[-<>+*%&\|\^/])=?', Operator, 
'slashstartsregex'),
+            (r'[{(\[;,]', Punctuation, 'slashstartsregex'),
+            (r'[})\].]', Punctuation),
+            
(r'(for|in|while|do|break|return|continue|switch|case|default|if|else|'
+             r'throw|try|catch|finally|new|delete|typeof|instanceof|void|'
+             r'this)\b', Keyword, 'slashstartsregex'),
+            (r'(var|let|const|with|function)\b', Keyword.Declaration, 
'slashstartsregex'),
+            
(r'(abstract|boolean|byte|char|class|const|debugger|double|enum|export|'
+             
r'extends|final|float|goto|implements|import|int|interface|long|native|'
+             
r'package|private|protected|public|short|static|super|synchronized|throws|'
+             r'transient|volatile)\b', Keyword.Reserved),
+            (r'(true|false|null|NaN|Infinity|undefined)\b', Keyword.Constant),
+            (r'(Array|Boolean|Date|Error|Function|Math|netscape|'
+             r'Number|Object|Packages|RegExp|String|sun|decodeURI|'
+             r'decodeURIComponent|encodeURI|encodeURIComponent|'
+             r'Error|eval|isFinite|isNaN|parseFloat|parseInt|document|this|'
+             r'window)\b', Name.Builtin),
+            # Match stuff like: module name {...}
+            (r'\b(module)(\s*)(\s*[a-zA-Z0-9_?.$][\w?.$]*)(\s*)',
+             bygroups(Keyword.Reserved, Text, Name.Other, Text), 
'slashstartsregex'),
+            # Match variable type keywords
+            (r'\b(string|bool|number)\b', Keyword.Type),
+            # Match stuff like: constructor
+            (r'\b(constructor|declare|interface|as|AS)\b', Keyword.Reserved),
+            # Match stuff like: super(argument, list)
+            (r'(super)(\s*)\(([a-zA-Z0-9,_?.$\s]+\s*)\)',
+             bygroups(Keyword.Reserved, Text), 'slashstartsregex'),
+            # Match stuff like: function() {...}
+            (r'([a-zA-Z_?.$][\w?.$]*)\(\) \{', Name.Other, 'slashstartsregex'),
+            # Match stuff like: (function: return type)
+            (r'([a-zA-Z0-9_?.$][\w?.$]*)(\s*:\s*)([a-zA-Z0-9_?.$][\w?.$]*)',
+             bygroups(Name.Other, Text, Keyword.Type)),
+            # Match stuff like: type Foo = Bar | Baz
+            (r'\b(type)(\s*)([a-zA-Z0-9_?.$]+)(\s*)(=)(\s*)',
+             bygroups(Keyword.Reserved, Text, Name.Other, Text, Operator, 
Text), 'typeexp'),
+            (r'[$a-zA-Z_][a-zA-Z0-9_]*', Name.Other),
+            (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
+            (r'0x[0-9a-fA-F]+', Number.Hex),
+            (r'[0-9]+', Number.Integer),
+            (r'"(\\\\|\\"|[^"])*"', String.Double),
+            (r"'(\\\\|\\'|[^'])*'", String.Single),
+        ]
+    }
diff --git a/src/api/exts/tsref.py b/src/api/exts/tsref.py
new file mode 100644
index 0000000..ae10832
--- /dev/null
+++ b/src/api/exts/tsref.py
@@ -0,0 +1,233 @@
+"""
+  This file is part of GNU TALER.
+  Copyright (C) 2014, 2015 GNUnet e.V. and INRIA
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Lesser General Public License as published by the Free 
Software
+  Foundation; either version 2.1, or (at your option) any later version.
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
details.
+  You should have received a copy of the GNU Lesser General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+
+  @author Florian Dold
+"""
+
+"""
+This extension adds a new lexer "tsref" for TypeScript, which
+allows reST-style links inside comments (`LinkName`_),
+and semi-automatically adds links to the definition of types.
+
+For type TYPE, a reference to tsref-type-TYPE is added.
+
+Known bugs and limitations:
+ - The way the extension works right now interferes wiht
+   Sphinx's caching, the build directory should be cleared
+   before every build.
+"""
+
+
+from pygments.util import get_bool_opt
+from pygments.token import Name, Comment, Token, _TokenType
+from pygments.filter import Filter
+from sphinx.highlighting import PygmentsBridge
+from sphinx.builders.html import StandaloneHTMLBuilder
+from sphinx.pygments_styles import SphinxStyle
+from pygments.formatters import HtmlFormatter
+from docutils import nodes
+from docutils.nodes import make_id
+import re
+
+
+_escape_html_table = {
+    ord('&'): u'&amp;',
+    ord('<'): u'&lt;',
+    ord('>'): u'&gt;',
+    ord('"'): u'&quot;',
+    ord("'"): u'&#39;',
+}
+
+
+class LinkingHtmlFormatter(HtmlFormatter):
+    def __init__(self, **kwargs):
+        super(LinkingHtmlFormatter, self).__init__(**kwargs)
+        self._builder = kwargs['_builder']
+
+    def _fmt(self, value, tok):
+        cls = self._get_css_class(tok)
+        href = tok_getprop(tok, "href")
+        caption = tok_getprop(tok, "caption")
+        content = caption if caption is not None else value
+        if href:
+            value = '<a style="color:inherit;text-decoration:underline" 
href="%s">%s</a>' % (href, content)
+        if cls is None or cls == "":
+            return value
+        return '<span class="%s">%s</span>' % (cls, value)
+
+    def _format_lines(self, tokensource):
+        """
+        Just format the tokens, without any wrapping tags.
+        Yield individual lines.
+        """
+        lsep = self.lineseparator
+        escape_table = _escape_html_table
+
+        line = ''
+        for ttype, value in tokensource:
+            link = get_annotation(ttype, "link")
+
+            parts = value.translate(escape_table).split('\n')
+
+            if len(parts) == 0:
+                # empty token, usually should not happen
+                pass
+            elif len(parts) == 1:
+                # no newline before or after token
+                line += self._fmt(parts[0], ttype)
+            else:
+                line += self._fmt(parts[0], ttype)
+                yield 1, line + lsep
+                for part in parts[1:-1]:
+                    yield 1, self._fmt(part, ttype) + lsep
+                line = self._fmt(parts[-1], ttype)
+
+        if line:
+            yield 1, line + lsep
+
+
+class MyPygmentsBridge(PygmentsBridge):
+    def __init__(self, builder, trim_doctest_flags):
+        self.dest = "html"
+        self.trim_doctest_flags = trim_doctest_flags
+        self.formatter_args = {'style': SphinxStyle, '_builder': builder}
+        self.formatter = LinkingHtmlFormatter
+
+
+class MyHtmlBuilder(StandaloneHTMLBuilder):
+    name = "html-linked"
+    def init_highlighter(self):
+        if self.config.pygments_style is not None:
+            style = self.config.pygments_style
+        elif self.theme:
+            style = self.theme.get_confstr('theme', 'pygments_style', 'none')
+        else:
+            style = 'sphinx'
+        self.highlighter = MyPygmentsBridge(self, 
self.config.trim_doctest_flags)
+
+    def write_doc(self, docname, doctree):
+        self._current_docname = docname
+        super(MyHtmlBuilder, self).write_doc(docname, doctree)
+
+
+def get_annotation(tok, key):
+    if not hasattr(tok, "kv"):
+        return None
+    return tok.kv.get(key)
+
+
+def copy_token(tok):
+    new_tok = _TokenType(tok)
+    # This part is very fragile against API changes ...
+    new_tok.subtypes = set(tok.subtypes)
+    new_tok.parent = tok.parent
+    return new_tok
+
+
+def tok_setprop(tok, key, value):
+    tokid = id(tok)
+    e = token_props.get(tokid)
+    if e is None:
+        e = token_props[tokid] = (tok, {})
+    _, kv = e
+    kv[key] = value
+
+
+def tok_getprop(tok, key):
+    tokid = id(tok)
+    e = token_props.get(tokid)
+    if e is None:
+        return None
+    _, kv = e
+    return kv.get(key)
+
+
+link_reg = re.compile(r"`([^`<]+)\s*(?:<([^>]+)>)?\s*`_")
+
+# Map from token id to props.
+# Properties can't be added to tokens
+# since they derive from Python's tuple.
+token_props = {}
+
+
+class LinkFilter(Filter):
+    def __init__(self, app, **options):
+        self.app = app
+        Filter.__init__(self, **options)
+
+    def filter(self, lexer, stream):
+        id_to_doc = self.app.env.domaindata.get("_tsref", {})
+        for ttype, value in stream:
+            if ttype in Token.Keyword.Type:
+                defname = make_id('tsref-type-' + value);
+                t = copy_token(ttype)
+                if defname in id_to_doc:
+                    docname = id_to_doc[defname]
+                    href = self.app.builder.get_target_uri(docname) + "#" + 
defname
+                    tok_setprop(t, "href", href)
+
+                yield t, value
+            elif ttype in Token.Comment:
+                last = 0
+                for m in re.finditer(link_reg, value):
+                    pre = value[last:m.start()]
+                    if pre:
+                        yield ttype, pre
+                    t = copy_token(ttype)
+                    x1, x2 = m.groups()
+                    if x2 is None:
+                        caption = x1.strip()
+                        id = make_id(x1)
+                    else:
+                        caption = x1.strip()
+                        id = make_id(x2)
+                    if id in id_to_doc:
+                        docname = id_to_doc[id]
+                        href = self.app.builder.get_target_uri(docname) + "#" 
+ id
+                        tok_setprop(t, "href", href)
+                        tok_setprop(t, "caption", caption)
+                    else:
+                        self.app.builder.warn("unresolved link target in 
comment: " + id)
+                    yield t, m.group(1)
+                    last = m.end()
+                post = value[last:]
+                if post:
+                    yield ttype, post
+            else:
+                yield ttype, value
+
+
+
+def remember_targets(app, doctree):
+    docname = app.env.docname
+    id_to_doc = app.env.domaindata.get("_tsref", None)
+    if id_to_doc is None:
+        id_to_doc = app.env.domaindata["_tsref"] = {}
+    for node in doctree.traverse():
+        if not isinstance(node, nodes.Element):
+            continue
+        ids = node.get("ids")
+        if ids:
+            for id in ids:
+                id_to_doc[id] = docname
+
+
+def setup(app): 
+    from sphinx.highlighting import lexers
+    from pygments.token import Name
+    from pygments.filters import NameHighlightFilter
+    from tslex import BetterTypeScriptLexer
+    lexer = BetterTypeScriptLexer()
+    lexer.add_filter(LinkFilter(app))
+    app.add_lexer('tsref', lexer)
+    app.add_builder(MyHtmlBuilder)
+    app.connect("doctree-read", remember_targets)
diff --git a/src/api/global-licensing.rst b/src/api/global-licensing.rst
new file mode 100644
index 0000000..7a5e822
--- /dev/null
+++ b/src/api/global-licensing.rst
@@ -0,0 +1,215 @@
+===========================
+Taler licensing information
+===========================
+
+This file gives an overview of all Taler component's licensing and of
+runtime dependencies thereof. For "component" here is meant a set of
+source files which can be retrieved from a single repository.  If
+components consist of sources under different licensing regimes, i.e.
+because we want to enable third party developments to easily integrate
+with Taler, those are described as well.
+
+All components are generally released under Lesser GPL, GPL or Affero
+GPL.  The main strategy is for libraries that third parties may need
+to integrate with Taler to be under LGPL, standalone binaries and
+testcases to be under GPL, and Web servers implementing Web services
+to be under AGPL.
+
++++++++++++++++++++++++++
+API (git://taler.net/api)
++++++++++++++++++++++++++
+
+The specification has been jointly developed by INRIA and by individuals
+being under the juridical subject called 'GNUnet e.V.'. For each source
+file, the header indicated whose is holding the copyright, since some
+parts have been taken "verbatim" from the GNUnet e.V. foundation, and
+some other have been developed at INRIA "ex novo".
+
+Generally, GNU GPLv3 license is used for them; see COPYING.GPL.
+
+
+--------------------
+Runtime dependencies
+--------------------
+This component has no runtime dependencies as it is supposed to generate
+HTML.
+
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Firefox/Android/Python Wallet (git://taler.net/wallet)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+This project includes contributions from INRIA and GNUnet
+e.V. developers.  Please refer to each source file to obtain
+information about the copyright holder. The GNU GPLv3 is used as the
+license for Wallets.  Some components may be under the LGPL.
+
+--------------------
+Runtime dependencies
+--------------------
+
+The following list encompasses all the runtime dependencies for this
+project, and gives the copyright holder for each of them:
+
+* libgnunetutil: GPLv3+, GNUnet e.V.
+* libgnunetjson: GPLv3+, GNUnet e.V.
+* libgcrypt: LGPL, Free Software Foundation
+* libunistring: LGPL, Free Software Foundation
+* Python:   Python Software Foundation License, LGPL-Compatible, Python 
Software Foundation
+* Mozilla Firefox:   Mozilla Public License, LGPL-Compatible, Mozilla 
Foundation
+
+
++++++++++++++++++++++++++++++++++++++++++++++++++++
+WebExtensions Wallet (git://taler.net/wallet-webex)
++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+The TypeScript code was developed 100% at INRIA, but the project
+involves compiling libgnunetutil and libtalerutil to JavaScript, and
+thus depends on software from GNUnet e.V.
+
+Each source carries its own copyright holder(s), but it is generally
+licensed under GPLv3+.
+
+--------------------
+Runtime dependencies
+--------------------
+
+The following list encompasses all the runtime dependencies for this
+project, and gives the copyright holder for each of them:
+
+* libgnunetutil: GPLv3+, GNUnet e.V.
+* libgnunetjson: GPLv3+, GNUnet e.V.
+* libgcrypt: LGPL, Free Software Foundation
+* libunistring: LGPL, Free Software Foundation
+
+Note that these dependencies are compiled into the extension and do
+not appear as separate binary files.
+
+
++++++++++++++++++++++++++++++++++++
+Merchant (git://taler.net/merchant)
++++++++++++++++++++++++++++++++++++
+
+This project contains code under two different licenses, and whose
+copyright is held by INRIA and/or GNUnet e.V..  Please refer to each
+source file to know which party holds the copyright.
+
+Source files are located in the following directories:
+
+* src/lib/
+* src/backend/
+* src/backenddb/
+* src/include/
+* src/tests/
+* examples/blog/
+* examples/shop/
+* copylib/
+
+In examples/blog/articles/ we included a book by Richard Stallman.
+It comes with its own permissive license (see COPYING in the
+directory).
+
+
+The merchant's backend (i.e. all the code in src/backend/) is under
+the GNU Affero GPL as it depends on libgnunetutil.  Note that the use
+of the Affero GPL has little impact as the backend is not supposed to
+be directly accessible to the Internet).  The license for this code is
+in COPYING.GPL and COPYING.AGPL.
+
+The merchant's frontend logic (i.e. JavaScript interacting with
+the wallet, sample code for a shop) is under the GNU LGPL (but
+we may choose to change this to be in the public domain or
+BSD-licensed if necessary; the code is so short that there is
+anyway the question whether it is copyrightable).  Under this same
+license, it comes the merchant library (src/lib/) as it can be linked
+with more diverse licensed software.  The license text for this code
+is in COPYING.LGPL.
+
+
+
+--------------------
+Runtime dependencies
+--------------------
+
+The following list encompasses all the runtime dependencies for this
+project, and gives the copyright holder for each of them:
+
+* libjansson: MIT License, AGPL- and LGPL-Compatible, owned by Petri Lehtinen 
and other individuals
+* libgcrypt: LGPL, owned by Free Software Foundation
+* postgresql: PostgreSQL License, AGPL- and LGPL-Compatible, owned by The 
PostgreSQL Global Development Group
+* libgnunetutil (in all of its variants): GPLv3+, owned by GNUnet e.V.
+* PHP:  PHP License, AGPL- and LGPL-Compatible, owned by The PHP Group
+
++++++++++++++++++++++++++++
+Bank (git://taler.net/bank)
++++++++++++++++++++++++++++
+
+---------
+Licensing
+---------
+
+This project has been developed by INRIA.  For each source file, the
+header indicated whose is holding the copyright.  The licensing plan
+for the bank is to use the Affero GPLv3+.
+
+Source files of interest are located in the following directories:
+(The repository holds also scaffolded files autogenerated by Django,
+which do not have legal significance in this context.)
+
+* TalerBank/Bank/
+* TalerBank/Bank/templates/
+* TalerBank/my-static/
+* website/
+
+--------------------
+Runtime dependencies
+--------------------
+
+The following list encompasses all the runtime dependencies for this
+project, and gives the copyright holder for each of them:
+
+* Django:   BSD License, AGPL-Compatible, owned by Django Software Foundation
+* validictory:   BSD License, AGPL-Compatible, owned by James Turk
+* django-simple-math-captcha:   Apache Software License, LGPL-Compatible 
(FIXME), Brandon Taylor
+* requests:   Apache2 License, AGPL-Compatible, owned by Kenneth Reitz
+* Python:   Python Software Foundation License, AGPL-Compatible, Python 
Software Foundation
+* PHP:   PHP License, AGPL-Compatible, owned by The PHP Group
+
+
+.. _exchange-repo:
+
++++++++++++++++++++++++++++++++++++
+Exchange (git://taler.net/exchange)
++++++++++++++++++++++++++++++++++++
+
+This component is based on code initially developed in Munich for
+GNUnet e.V.  Most recent improvements and maintenance has been done at
+Inria.  The copyright is thus shared between both institutions.
+
+The licensing for exported libraries to access the exchange is LGPL,
+the exchange itself is under AGPL, and testcases and standalone
+binaries are under GPL.
+
+
+--------------------
+Runtime dependencies
+--------------------
+
+The following list encompasses all the runtime dependencies for this
+project, and gives the copyright holder for each of them:
+
+* libjansson: MIT License, AGPL- and LGPL-Compatible, owned by Petri Lehtinen 
and other individuals
+* libgcrypt: LGPL, owned by Free Software Foundation
+* postgresql: PostgreSQL License, AGPL- and LGPL-Compatible, owned by The 
PostgreSQL Global Development Group
+* libgnunetutil (in all of its variants): GPLv3+, owned by GNUnet e.V.
+* libgnunetjson: GPLv3+, GNUnet e.V.
+
+
++++++++++++++++++++++++++++++++++++++++++
+Web includes (git://taler.net/web-common)
++++++++++++++++++++++++++++++++++++++++++
+
+All copyright owned by INRIA (but questionable whether creativity
+threshold for copyright is even met).
+
+Sources are licensed under the GNU LGPL.
diff --git a/src/api/index.rst b/src/api/index.rst
new file mode 100644
index 0000000..e883b58
--- /dev/null
+++ b/src/api/index.rst
@@ -0,0 +1,71 @@
+..
+  This file is part of GNU TALER.
+  Copyright (C) 2014-2018 GNUnet e.V.
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU General Public License as published by the Free Software
+  Foundation; either version 2.1, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
details.
+
+  You should have received a copy of the GNU Lesser General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+
+  @author Florian Dold
+  @author Benedikt Muller
+  @author Sree Harsha Totakura
+  @author Marcello Stanisci
+  @author Christian Grothoff
+
+GNU Taler Documentation
+=======================
+
+We are building an anonymous, taxable payment system using modern
+cryptography.  Customers will use traditional money transfers to send
+money to a digital Exchange and in return receive (anonymized) digital
+cash.  Customers can use this digital cash to anonymously pay
+Merchants.  Merchants can redeem the digital cash for traditional
+money at the digital Exchange.  As Merchants are not anonymous, they can
+be taxed, enabling income or sales taxes to be withheld by the state
+while providing anonymity for Customers.
+
+Cryptography is used to ensure that none of the participants can
+defraud the others without being detected immediately; however, in
+practice a fradulent Exchange might go bankrupt instead of paying the
+Merchants and thus the Exchange will need to be audited regularly like
+any other banking institution.
+
+The system will be based on free software and open protocols.
+
+In this document, we describe the REST-based APIs between the various
+components, internal architecture of key components, and how to get them
+installed.
+
+--------------------------------------
+Taler HTTP Core Protocol Specification
+--------------------------------------
+
+The *Protocol Specification* defines the HTTP-based, predominantly RESTful
+interfaces between the core components of Taler.
+
+.. toctree::
+  :maxdepth: 2
+
+  api-common
+  api-error
+  api-exchange
+  api-merchant
+  api-auditor
+  api-bank
+  wireformats
+
+---------
+Licensing
+---------
+
+.. toctree::
+  :maxdepth: 2
+
+  global-licensing
diff --git a/src/api/wireformats.rst b/src/api/wireformats.rst
new file mode 100644
index 0000000..12d2363
--- /dev/null
+++ b/src/api/wireformats.rst
@@ -0,0 +1,70 @@
+.. _wireformats:
+
+Wire Transfer Methods
+=====================
+
+A wire transfer is essential for the exchange to transfer funds into a 
merchant's
+account upon a successful deposit (see :ref:`deposit request <deposit>`).  The
+merchant has to include the necessary information for the exchange to initiate 
the
+wire transfer.
+
+The information required for wire transfer depends on the method of wire 
transfer
+used.  Since the wire transfers differ for each region, we document here the
+ones currently supported by the exchange.
+
+X-TALER-BANK
+------------
+
+The "x-taler-bank" wire format is used for testing and for integration with 
Taler's
+simple "bank" system which in the future might be useful to setup a bank
+for a local / regional currency or accounting system.  Using the 
@code{x-taler-bank}
+wire method in combination with the Taler's bank, it is thus possible to
+fully test the Taler system without using "real" currencies.  The URL
+format for "x-taler-bank" is simple, in that it only specifies an account
+number and the URL of the bank:
+
+  *  payto://x-taler-bank/BANK_URI/ACCOUNT_NUMBER
+
+The account number given must be a positive 53-bit integer.  As with
+any payto://-URI, additional fields may be present (after a ?), but
+are not required.  The BANK_URI may include a port number. If none is
+given, @code{https} over port 443 is assumed.  If a port number is
+given, @code{http} over the given port is to be used.  Note that this
+means that you cannot run an x-taler-bank over @code{https} on a
+non-canonical port.
+
+Note that a particular exchange is usually only supporting one
+particular bank with the "x-taler-bank" wire format, so it is not
+possible for a merchant with an account at a different bank to use
+"x-taler-bank" to transfer funds across banks. After all, this is for
+testing and not for real banking.
+
+The "x-taler-bank" method is implemented by the @code{taler_bank} plugin.
+
+
+SEPA
+----
+
+The Single Euro Payments Area (SEPA) [#sepa]_ is a regulation for electronic
+payments.  Since its adoption in 2012, all of the banks in the Eurozone and 
some
+banks in other countries adhere to this standard for sending and receiving
+payments.  Note that the currency of the transfer will (currently) always be 
*EUR*.  In
+case the receiving account is in a currency other than EURO, the receiving bank
+may covert the amount into that currency; currency exchange charges may be
+levied by the receiving bank.
+
+For the merchant to receive deposits through SEPA, the deposit request must
+follow the payto:// specification for SEPA:
+
+  *  payto://sepa/IBAN
+
+
+The implementation of the @code{ebics} plugin which is envisioned to
+support the @code{sepa} method is currently incomplete.  Specifically,
+we need a working implementation of `libebics` which is a sub-project
+trying to implement the EBICS [#ebics]_ standard.
+
+.. [#sepa] SEPA - Single Euro Payments Area:
+           http://www.ecb.europa.eu/paym/sepa/html/index.en.html
+.. [#ebics] EBCIS - European Banking Computer Interface Standard
+          http://www.ebics.org/

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]