taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

api-corebank.rst (62985B)


      1 ..
      2   This file is part of GNU TALER.
      3 
      4   Copyright (C) 2014-2025, 2026 Taler Systems SA
      5 
      6   TALER is free software; you can redistribute it and/or modify it under the
      7   terms of the GNU Affero General Public License as published by the Free Software
      8   Foundation; either version 2.1, or (at your option) any later version.
      9 
     10   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     11   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     12   A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
     13 
     14   You should have received a copy of the GNU Affero General Public License along with
     15   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     16 
     17 .. target audience: developer, core developer
     18 
     19 .. _corebank-api:
     20 
     21 ====================
     22 Taler Core Bank API
     23 ====================
     24 
     25 Introduction
     26 ------------
     27 
     28 The Libeufin bank provides a minimal core banking system.  In addition to that,
     29 it provides features for local/regional currencies.
     30 
     31 Version History
     32 ---------------
     33 
     34 The current protocol version is **v12**.
     35 
     36 * Android cashier app is currently targeting **v9**.
     37 
     38 **Version history:**
     39 
     40 * ``v10``: Update two factor authentication API to match Merchant Backend API
     41 * ``v11``: Add observability API
     42 * ``v12``: Add wire transfer API
     43 
     44 **Upcoming versions:**
     45 
     46 * None anticipated.
     47 
     48 **Ideas for future version:**
     49 
     50 * ``vXXX``: marker for features not yet targeted for release
     51 
     52 
     53 
     54 
     55 Config
     56 ------
     57 
     58 .. http:get:: /config
     59 
     60   Return the protocol version and configuration information about the bank.
     61   This specification corresponds to ``current`` protocol being version **v12**.
     62 
     63   **Response:**
     64 
     65   :http:statuscode:`200 OK`:
     66     Response is a `Config`.
     67 
     68   **Details:**
     69 
     70   .. ts:def:: Config
     71 
     72     interface Config {
     73       // Name of the API.
     74       name: "taler-corebank";
     75 
     76       // libtool-style representation of the Bank protocol version, see
     77       // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
     78       // The format is "current:revision:age".
     79       version: string;
     80 
     81       // Bank display name to be used in user interfaces.
     82       // For consistency use "Taler Bank" if missing.
     83       // @since **v4**, will become mandatory in the next version.
     84       bank_name?: string;
     85 
     86       // Advertised base URL to use when you sharing an URL with another
     87       // program.
     88       // @since **v4**.
     89       base_url?: string;
     90 
     91       // If 'true' the server provides local currency conversion support
     92       // If 'false' some parts of the API are not supported and return 501
     93       allow_conversion: boolean;
     94 
     95       // If 'true' anyone can register
     96       // If 'false' only admin can
     97       allow_registrations: boolean;
     98 
     99       // If 'true' account can delete themselves
    100       // If 'false' only admin can delete accounts
    101       allow_deletions: boolean;
    102 
    103       // If 'true' anyone can edit their name
    104       // If 'false' only admin can
    105       allow_edit_name: boolean;
    106 
    107       // If 'true' anyone can edit their cashout account
    108       // If 'false' only admin can
    109       allow_edit_cashout_payto_uri: boolean;
    110 
    111       // Default debt limit for newly created accounts
    112       default_debit_threshold: Amount;
    113 
    114       // Currency used by this bank.
    115       currency: string;
    116 
    117       // How the bank SPA should render this currency.
    118       currency_specification: CurrencySpecification;
    119 
    120       // TAN channels supported by the server
    121       supported_tan_channels: TanChannel[];
    122 
    123       // Wire transfer type supported by the bank.
    124       // Defaults to 'iban' is missing
    125       // @since **v4**, will become mandatory in the next version.
    126       wire_type?: string;
    127 
    128       // Wire transfer execution fees. Only applies to bank transactions and withdrawals.
    129       // @since **v4**, will become mandatory in the next version.
    130       wire_transfer_fees?: Amount;
    131 
    132       // Minimum wire transfer amount allowed. Only applies to bank transactions and withdrawals.
    133       // @since **v4**, will become mandatory in the next version.
    134       min_wire_transfer_amount?: Amount;
    135 
    136       // Maximum wire transfer amount allowed. Only applies to bank transactions and withdrawals.
    137       // @since **v4**, will become mandatory in the next version.
    138       max_wire_transfer_amount?: Amount;
    139     }
    140 
    141 
    142 
    143 Authentication
    144 --------------
    145 
    146 Some endpoints requires the client to authenticate using a bearer token. Tokens can be obtained or refreshed using the ``/accounts/$USERNAME/token`` endpoint.
    147 This endpoint support authentication via HTTP Basic auth (RFC 7617). When using Basic authentication, the user-id must be the bank's username, and the password the password of the corresponding user.
    148 
    149 The user ``admin`` is a special, hard-coded username. Some requests require the client to authenticate as administrator.
    150 
    151 .. warning::
    152 
    153   Since **v7** Basic authentication for endpoints other than ``/accounts/$USERNAME/token`` has been deprecated and will no longer be supported in the next release.
    154 
    155 .. http:post:: /accounts/$USERNAME/token
    156 
    157   Create an authentification token.
    158 
    159   **Request:**
    160 
    161   .. ts:def:: TokenRequest
    162 
    163     interface TokenRequest {
    164       // Scope for the token.
    165       scope: "readonly" | "readwrite" | "revenue" | "wiregateway" | "observability";
    166 
    167       // Custom token validity duration
    168       duration?: RelativeTime;
    169 
    170       // Is the token refreshable into a new token during its
    171       // validity?
    172       // Refreshable tokens effectively provide indefinite
    173       // access if they are refreshed in time.
    174       refreshable?: boolean;
    175 
    176       // Optional token description
    177       // @since **v4**
    178       description?: string;
    179     }
    180 
    181   **Response:**
    182 
    183   :http:statuscode:`200 Ok`:
    184     Response is a `TokenSuccessResponse`.
    185   :http:statuscode:`202 Accepted`:
    186     2FA is required for this operation. This returns the `ChallengeResponse` response. @since **v10**
    187   :http:statuscode:`401 Unauthorized`:
    188     Invalid or missing credentials.
    189   :http:statuscode:`403 Forbidden`:
    190     * ``TALER_EC_GENERIC_FORBIDDEN``: missing rights.
    191     * ``TALER_EC_BANK_ACCOUNT_LOCKED``: account is locked and cannot create new token using its password.
    192 
    193   **Details:**
    194 
    195   .. ts:def:: TokenSuccessResponse
    196 
    197     interface TokenSuccessResponse {
    198       // Expiration determined by the server.
    199       // Can be based on the token_duration
    200       // from the request, but ultimately the
    201       // server decides the expiration.
    202       expiration: Timestamp;
    203 
    204       // Opque access token.
    205       access_token: string;
    206     }
    207 
    208 .. http:delete:: /accounts/$USERNAME/token
    209 
    210   Invalidate the access token that is being used to make the request.
    211 
    212   **Authentication:**  The client must authenticate with a valid access token.
    213 
    214   **Response:**
    215 
    216   :http:statuscode:`204 No content`:
    217     The token have been deleted.
    218   :http:statuscode:`401 Unauthorized`:
    219     Invalid or missing credentials.
    220   :http:statuscode:`403 Forbidden`:
    221     Missing rights.
    222 
    223 .. http:get:: /accounts/$USERNAME/tokens
    224 
    225   Retrieve a subset of tokens related to $USERNAME.
    226   @since **v4**
    227 
    228   **Request:**
    229 
    230   :query limit: *Optional.*
    231     At most return the given number of results. Negative for descending by ``token_id``, positive for ascending by ``token_id``. Defaults to ``-20``. Since **v5**.
    232   :query offset: *Optional.*
    233     Starting ``token_id`` for :ref:`pagination <row-id-pagination>`. Since **v5**.
    234   :query delta: *Optional.*
    235     Deprecated since **v5**. Use *limit* instead.
    236   :query start: *Optional.*
    237     Deprecated since **v5**. Use *offset* instead.
    238 
    239   **Response:**
    240 
    241   :http:statuscode:`200 OK`:
    242     Response is a `TokenInfos`.
    243   :http:statuscode:`204 No content`:
    244     No tokens.
    245   :http:statuscode:`401 Unauthorized`:
    246     Invalid or missing credentials.
    247   :http:statuscode:`403 Forbidden`:
    248     Mmissing rights.
    249 
    250   **Details:**
    251 
    252   .. ts:def:: TokenInfos
    253 
    254     interface TokenInfos {
    255       tokens: TokenInfo[];
    256     }
    257 
    258   .. ts:def:: TokenInfo
    259 
    260     interface TokenInfo {
    261       // Time when the token was created.
    262       creation_time: Timestamp;
    263 
    264       // Expiration determined by the server.
    265       // Can be based on the token_duration
    266       // from the request, but ultimately the
    267       // server decides the expiration.
    268       expiration: Timestamp;
    269 
    270       // Scope for the token.
    271       scope: "readonly" | "readwrite" | "revenue" | "wiregateway";
    272 
    273       // Is the token refreshable into a new token during its
    274       // validity?
    275       // Refreshable tokens effectively provide indefinite
    276       // access if they are refreshed in time.
    277       refreshable: boolean;
    278 
    279       // Optional token description
    280       description?: string;
    281 
    282       // Time when the token was last used.
    283       last_access: Timestamp;
    284 
    285       // ID identifying the token
    286       token_id: Integer;
    287 
    288       // deprecated since **v9**. Use *token_id* instead.
    289       row_id: Integer;
    290     }
    291 
    292 .. http:delete:: /accounts/$USERNAME/tokens/$TOKEN_ID
    293 
    294   Delete an access token.
    295 
    296   **Response:**
    297 
    298   :http:statuscode:`204 No content`:
    299     The token have been deleted.
    300   :http:statuscode:`404 Not found`:
    301     Token ``$TOKEN_ID`` was not found.
    302   :http:statuscode:`401 Unauthorized`:
    303     Invalid or missing credentials.
    304   :http:statuscode:`403 Forbidden`:
    305     Missing rights.
    306 
    307 Bank Web UI
    308 -----------
    309 
    310 The web UI for the bank is typically served under ``/``.
    311 
    312 
    313 Account Management
    314 ------------------
    315 
    316 .. _bank-account-register:
    317 
    318 .. http:post:: /accounts
    319 
    320   Create a new bank account.  Depending on the configuration,
    321   the account creation is self-serve, or only restricted to
    322   the administrators.
    323 
    324   **Request:**
    325 
    326   .. ts:def:: RegisterAccountRequest
    327 
    328     interface RegisterAccountRequest {
    329       // Username of the account
    330       // Must match [a-zA-Z0-9-._~]{1, 126}
    331       username: string;
    332 
    333       // Password of the account used for authentication
    334       password: string;
    335 
    336       // Legal name of the account owner
    337       name: string;
    338 
    339       // Make this account visible to anyone?
    340       // Defaults to false.
    341       is_public?: boolean;
    342 
    343       // Make this account a taler exchange account?
    344       // If true:
    345       // - incoming transactions to the account that do not
    346       //   have a valid reserve public key are automatically
    347       // - the account provides the taler-wire-gateway-api endpoints
    348       // Defaults to false.
    349       is_taler_exchange?: boolean;
    350 
    351       // Addresses where to send the TAN for protected operations.
    352       contact_data?: ChallengeContactData;
    353 
    354       // Payto URI of a fiat bank account.
    355       // Payments will be sent to this bank account
    356       // when the user wants to convert the regional currency
    357       // back to fiat currency outside bank.
    358       cashout_payto_uri?: string;
    359 
    360       // Simple payto URI of this bank account.
    361       // Used mostly for testing, this field is ignored if the bank payment
    362       // method is not IBAN.
    363       payto_uri?: string;
    364 
    365       // If present, set the max debit allowed for this user
    366       // Only admin can set this property.
    367       debit_threshold?: Amount;
    368 
    369       // If present, set the user conversion rate class
    370       // Only admin can set this property.
    371       // @since **v9**
    372       conversion_rate_class_id?: Integer;
    373 
    374       // @deprecated in **v10**
    375       // If present, enables 2FA and set the TAN channel used for challenges
    376       // Only admin can set this property, other user can reconfig their account
    377       // after creation.
    378       tan_channel?: TanChannel;
    379 
    380       // If present, enables 2FA and set the TAN channels used for challenges
    381       // Only admin can set this property, other user can reconfig their account
    382       // after creation.
    383       // @since **v10**
    384       tan_channels?: TanChannel[];
    385 
    386       // @deprecated in **v9**, use conversion_rate_class_id instead
    387       min_cashout?: Amount;
    388     }
    389 
    390   .. ts:def:: ChallengeContactData
    391 
    392     interface ChallengeContactData {
    393       // E-Mail address
    394       email?: EmailAddress;
    395 
    396       // Phone number.
    397       phone?: PhoneNumber;
    398     }
    399 
    400 
    401   **Response:**
    402 
    403   :http:statuscode:`200 OK`:
    404     Response is a `RegisterAccountResponse`.
    405   :http:statuscode:`400 Bad request`:
    406     Input data was invalid.  For example, the client specified a invalid
    407     phone number or e-mail address.
    408   :http:statuscode:`401 Unauthorized`:
    409     Invalid or missing credentials.
    410   :http:statuscode:`403 Forbidden`:
    411     Missing rights.
    412   :http:statuscode:`409 Conflict`:
    413     * ``TALER_EC_BANK_REGISTER_USERNAME_REUSE`` : username already used.
    414     * ``TALER_EC_BANK_REGISTER_PAYTO_URI_REUSE`` : payto URI already used.
    415     * ``TALER_EC_BANK_UNALLOWED_DEBIT`` : admin account does not have sufficient funds to grant bonus.
    416     * ``TALER_EC_BANK_RESERVED_USERNAME_CONFLICT`` : a reserved username was attempted, like ``admin`` or ``bank``
    417     * ``TALER_EC_BANK_NON_ADMIN_PATCH_DEBT_LIMIT`` : a non-admin user has tried to create an account with a customer debt limit.
    418     * ``TALER_EC_BANK_NON_ADMIN_SET_CONVERSION_RATE_CLASS`` : a non-admin user has tried to create an account with a conversion rate class. Since **v9**
    419     * ``TALER_EC_BANK_NON_ADMIN_SET_TAN_CHANNEL`` : a non-admin user has tried to create an account with 2fa.
    420     * ``TALER_EC_BANK_TAN_CHANNEL_NOT_SUPPORTED``: ``tan_channel`` or one of ``tan_channels`` is not supported, check bank config to find supported ones.
    421     * ``TALER_EC_BANK_MISSING_TAN_INFO``: the user did not share any contact data where to send the TAN via ``tan_channel`` or one of ``tan_channels``.
    422     * ``TALER_EC_BANK_PASSWORD_TOO_SHORT``: password is shorter than 8 characters.
    423     * ``TALER_EC_BANK_PASSWORD_TOO_LONG``: password is longer than 64 characters.
    424     * ``TALER_EC_BANK_CONVERSION_RATE_CLASS_UNKNOWN`` : no conversion rate class found for this id. Since **v9**
    425 
    426   **Details:**
    427 
    428   .. ts:def:: RegisterAccountResponse
    429 
    430     interface RegisterAccountResponse {
    431       // Full payto URI of this bank account.
    432       internal_payto_uri: string;
    433     }
    434 
    435 .. _account-reconfig:
    436 
    437 .. http:patch:: /accounts/$USERNAME
    438 
    439   Allows reconfiguring the account data of ``$USERNAME``.
    440 
    441   **Request:**
    442 
    443   .. ts:def:: AccountReconfiguration
    444 
    445     interface AccountReconfiguration {
    446       // Addresses where to send the TAN for protected operations.
    447       contact_data?: ChallengeContactData;
    448 
    449       // Payto URI of a fiat bank account.
    450       // Payments will be sent to this bank account
    451       // when the user wants to convert the regional currency
    452       // back to fiat currency outside bank.
    453       // Only admin can change this property if not allowed in config
    454       // Sending null will disable cashout
    455       cashout_payto_uri?: string | null;
    456 
    457       // If present, change the legal name associated with $username.
    458       // Only admin can change this property if not allowed in config
    459       name?: string;
    460 
    461       // Make this account visible to anyone?
    462       is_public?: boolean;
    463 
    464       // If present, change the max debit allowed for this user
    465       // Only admin can change this property.
    466       debit_threshold?: Amount;
    467 
    468       // If present, set the user conversion rate class
    469       // Only admin can set this property.
    470       // Sending null will remove the class and switch to default class
    471       // @since **v9**
    472       conversion_rate_class_id?: Integer | null;
    473 
    474       // @deprecated in **v10**
    475       // If present, enables 2FA and set the TAN channel used for challenges
    476       // Sending null will disable 2FA
    477       tan_channel?: TanChannel | null;
    478 
    479       // If present and not empty, enables 2FA and set the TAN channels used for challenges
    480       // Sending null or an empty array will disable 2FA
    481       // @since **v10**
    482       tan_channels?: TanChannel[] | null;
    483 
    484       // @deprecated in **v9**, user conversion rate classes instead
    485       min_cashout?: Amount;
    486     }
    487 
    488   **Response:**
    489 
    490   :http:statuscode:`202 Accepted`:
    491     2FA is required for this operation. This returns the `ChallengeResponse` response. @since **v10**
    492   :http:statuscode:`204 No content`:
    493     Operation successful.
    494   :http:statuscode:`401 Unauthorized`:
    495     Invalid or missing credentials.
    496   :http:statuscode:`403 Forbidden`:
    497     Missing rights.
    498   :http:statuscode:`404 Not found`:
    499     The account pointed by ``$USERNAME`` was not found.
    500   :http:statuscode:`409 Conflict`:
    501     * ``TALER_EC_BANK_NON_ADMIN_PATCH_LEGAL_NAME`` : a non-admin user has tried to change their legal name.
    502     * ``TALER_EC_BANK_NON_ADMIN_PATCH_CASHOUT`` : a non-admin user has tried to change their cashout account.
    503     * ``TALER_EC_BANK_NON_ADMIN_PATCH_DEBT_LIMIT`` : a non-admin user has tried to change their debt limit.
    504     * ``TALER_EC_BANK_NON_ADMIN_SET_CONVERSION_RATE_CLASS`` : a non-admin user has tried to create an account with a conversion rate class. Since **v9**
    505     * ``TALER_EC_BANK_TAN_CHANNEL_NOT_SUPPORTED`` : ``tan_channel`` or one of ``tan_channels`` is not supported, check bank config to find supported ones.
    506     * ``TALER_EC_BANK_MISSING_TAN_INFO`` : the user did not share any contact data where to send the TAN via ``tan_channel`` or one of ``tan_channels``.
    507     * ``TALER_EC_BANK_CONVERSION_RATE_CLASS_UNKNOWN`` : no conversion rate class found for this id. Since **v9**
    508 
    509 
    510 .. _account-password-reconfig:
    511 
    512 .. http:patch:: /accounts/$USERNAME/auth
    513 
    514   Allows changing the account's password.
    515 
    516 
    517   **Request:**
    518 
    519   .. ts:def:: AccountPasswordChange
    520 
    521     interface AccountPasswordChange {
    522       // Old password. If present it need to match the current
    523       // password before updating.
    524       old_password?: string;
    525       // New password.
    526       new_password: string;
    527     }
    528 
    529   **Response:**
    530 
    531   :http:statuscode:`202 Accepted`:
    532     2FA is required for this operation. This returns the `ChallengeResponse` response. @since **v10**
    533   :http:statuscode:`204 No content`:
    534     Operation successful.
    535   :http:statuscode:`404 Not found`:
    536     The account pointed by ``$USERNAME`` was not found.
    537   :http:statuscode:`401 Unauthorized`:
    538     Invalid or missing credentials.
    539   :http:statuscode:`403 Forbidden`:
    540     Missing rights.
    541   :http:statuscode:`409 Conflict`:
    542     * ``TALER_EC_BANK_NON_ADMIN_PATCH_MISSING_OLD_PASSWORD``: a non-admin user has tried to change their password whihout providing the current one.
    543     * ``TALER_EC_BANK_PATCH_BAD_OLD_PASSWORD`` : provided old password does not match current password.
    544     * ``TALER_EC_BANK_PASSWORD_TOO_SHORT``: new password is shorter than 8 characters.
    545     * ``TALER_EC_BANK_PASSWORD_TOO_LONG``: new password is longer than 64 characters.
    546 
    547 
    548 .. _delete-account:
    549 
    550 .. http:delete:: /accounts/$USERNAME
    551 
    552   Delete the account whose username is ``$USERNAME``.  The deletion
    553   succeeds only if the balance is *zero*.  Typically only available to
    554   the administrator, but can be configured to allow ordinary users too.
    555 
    556   **Response:**
    557 
    558   :http:statuscode:`202 Accepted`:
    559     2FA is required for this operation. This returns the `ChallengeResponse` response. @since **v10**
    560   :http:statuscode:`204 No content`:
    561     The account was successfully deleted.
    562   :http:statuscode:`401 Unauthorized`:
    563     Invalid or missing credentials.
    564   :http:statuscode:`403 Forbidden`:
    565     Missing rights.
    566   :http:statuscode:`404 Not found`:
    567     The account pointed by ``$USERNAME`` was not found.
    568   :http:statuscode:`409 Conflict`:
    569     * ``TALER_EC_BANK_RESERVED_USERNAME_CONFLICT`` : a reserved username was attempted, like ``admin`` or ``bank``.
    570     * ``TALER_EC_BANK_ACCOUNT_BALANCE_NOT_ZERO``: the account balance was not zero.
    571 
    572 .. _account-list:
    573 
    574 .. http:get:: /public-accounts
    575 
    576   Show those accounts whose histories are publicly visible.  For example,
    577   accounts from donation receivers.  As such, this request is unauthenticated.
    578 
    579   **Request:**
    580 
    581   :query limit: *Optional.*
    582     At most return the given number of results. Negative for descending by ``row_id``, positive for ascending by ``row_id``. Defaults to ``-20``. Since **v5**.
    583   :query offset: *Optional.*
    584     Starting ``row_id`` for :ref:`pagination <row-id-pagination>`. Since **v5**.
    585   :query filter_name: *Optional.*
    586     Pattern to filter on the account's legal name.  Given
    587     the filter 'foo', all the results will **contain**
    588     'foo' in their legal name.  Without this option,
    589     all the existing accounts are returned.
    590   :query delta: *Optional.*
    591     Deprecated since **v5**. Use *limit* instead.
    592   :query start: *Optional.*
    593     Deprecated since **v5**. Use *offset* instead.
    594 
    595   **Response:**
    596 
    597   :http:statuscode:`200 OK`:
    598     Response is a `PublicAccountsResponse`.
    599   :http:statuscode:`204 No content`:
    600     No public account.
    601 
    602   **Details:**
    603 
    604   .. ts:def:: PublicAccountsResponse
    605 
    606     interface PublicAccountsResponse {
    607       public_accounts: PublicAccount[];
    608     }
    609 
    610   .. ts:def:: PublicAccount
    611 
    612     interface PublicAccount {
    613       // Username of the account
    614       username: string;
    615 
    616       // Full payto URI of this bank account.
    617       payto_uri: string;
    618 
    619       // Current balance of the account
    620       balance: Balance;
    621 
    622       // Is this a taler exchange account?
    623       is_taler_exchange: boolean;
    624 
    625       // Opaque unique ID used for pagination.
    626       // @since **v4**, will become mandatory in the next version.
    627       row_id?: Integer;
    628     }
    629 
    630 .. http:get:: /accounts
    631 
    632   Obtains a list of the accounts registered at the bank.
    633   It returns only the information that this API handles, without
    634   any balance or transactions list.
    635   This request is only available to the administrator.
    636 
    637   **Request:**
    638 
    639   :query limit: *Optional.*
    640     At most return the given number of results. Negative for descending by ``row_id``, positive for ascending by ``row_id``. Defaults to ``-20``. Since **v5**.
    641   :query offset: *Optional.*
    642     Starting ``row_id`` for :ref:`pagination <row-id-pagination>`. Since **v5**.
    643   :query filter_name: *Optional.*
    644     Pattern to filter on the account's legal name.  Given
    645     the filter 'foo', all the accounts will **contain**
    646     'foo' in their legal name.  Without this option,
    647     all the existing accounts are returned.
    648   :query conversion_rate_class_id: *Optional.*
    649     Id of a conversion rate class. Given the filter '1', the accounts will be part of the conversion rate class 1. Given the filter '0', will have no conversion rate class. Without this option all the existing accounts are returned. Since **v9**.
    650   :query delta: *Optional.*
    651     Deprecated since **v5**. Use *limit* instead.
    652   :query start: *Optional.*
    653     Deprecated since **v5**. Use *offset* instead.
    654 
    655   **Response:**
    656 
    657   :http:statuscode:`200 OK`:
    658     At least one account was found.
    659     The server responds with a `ListBankAccountsResponse` object.
    660   :http:statuscode:`204 No Content`:
    661     No accounts were found for the given request.
    662   :http:statuscode:`401 Unauthorized`:
    663     Invalid or missing credentials.
    664   :http:statuscode:`403 Forbidden`:
    665     Missing rights.
    666 
    667   **Details:**
    668 
    669   .. ts:def:: ListBankAccountsResponse
    670 
    671     interface ListBankAccountsResponse {
    672       accounts: AccountMinimalData[];
    673     }
    674 
    675   .. ts:def:: Balance
    676 
    677     interface Balance {
    678       amount: Amount;
    679       credit_debit_indicator: "credit" | "debit";
    680     }
    681 
    682   .. ts:def:: AccountMinimalData
    683 
    684     interface AccountMinimalData {
    685       // Username of the account
    686       username: string;
    687 
    688       // Legal name of the account owner.
    689       name: string;
    690 
    691       // Full payto URI of this bank account.
    692       payto_uri: string;
    693 
    694       // Current balance of the account
    695       balance: Balance;
    696 
    697       // Number indicating the max debit allowed for the requesting user.
    698       debit_threshold: Amount;
    699 
    700       // Custom minimum cashout amount for this account.
    701       // If null or absent, the global conversion fee is used.
    702       // @since **v6**
    703       // @deprecated in **v9**, use conversion_rate_class_id instead
    704       min_cashout?: Amount;
    705 
    706       // Is this account visible to anyone?
    707       is_public: boolean;
    708 
    709       // Is this a taler exchange account?
    710       is_taler_exchange: boolean;
    711 
    712       // Is the account locked.
    713       // Defaults to false.
    714       // @deprecated since **v7**
    715       is_locked?: boolean;
    716 
    717       // Opaque unique ID used for pagination.
    718       // @since **v4**, will become mandatory in the next version.
    719       row_id?: Integer;
    720 
    721       // Current status of the account
    722       // active: the account can be used
    723       // locked: the account can be used but cannot create new tokens
    724       // @since **v7**
    725       // deleted: the account has been deleted but is retained for compliance
    726       // reasons, only the administrator can access it
    727       // Defaults to 'active' is missing
    728       // @since **v4**, will become mandatory in the next version.
    729       status?: "active" | "locked" | "deleted";
    730 
    731       // Conversion rate class of the user
    732       // Only present if conversion is activated on the server
    733       // @since **v9**
    734       conversion_rate_class_id?: Integer;
    735 
    736       // Conversion rate available to the user
    737       // Only present if conversion is activated on the server
    738       // @since **v9**
    739       conversion_rate?: ConversionRate;
    740     }
    741 
    742 .. _bank-account-info:
    743 
    744 .. http:get:: /accounts/$USERNAME
    745 
    746   Obtains information relative to the account owned by
    747   ``$USERNAME``.  The request is available to the administrator
    748   and ``$USERNAME`` itself.
    749 
    750   **Response:**
    751 
    752   :http:statuscode:`200 OK`:
    753     The bank responds with an `AccountData` object.
    754   :http:statuscode:`401 Unauthorized`:
    755     Invalid or missing credentials.
    756   :http:statuscode:`403 Forbidden`:
    757     Missing rights.
    758   :http:statuscode:`404 Not found`:
    759     The account pointed by ``$USERNAME`` was not found.
    760 
    761   **Details:**
    762 
    763   .. ts:def:: AccountData
    764 
    765     interface AccountData {
    766       // Legal name of the account owner.
    767       name: string;
    768 
    769       // Available balance on the account.
    770       balance: Balance;
    771 
    772       // Full payto URI of the account.
    773       payto_uri: string;
    774 
    775       // Number indicating the max debit allowed for the requesting user.
    776       debit_threshold: Amount;
    777 
    778       // Custom minimum cashout amount for this account.
    779       // If null or absent, the global conversion fee is used.
    780       // @since **v6**
    781       // @deprecated in **v9**, use conversion_rate_class_id instead
    782       min_cashout?: Amount;
    783 
    784       // Addresses where to send the TAN for transactions.
    785       // Currently only used for cashouts.
    786       // If missing, cashouts will fail.
    787       // In the future, might be used for other transactions
    788       // as well.
    789       contact_data?: ChallengeContactData;
    790 
    791       // Full 'payto' URI of a fiat bank account where to send cashouts with
    792       // ``name`` as the 'receiver-name'.
    793       // This field is optional
    794       // because not all the accounts are required to participate
    795       // in the merchants' circuit.  One example is the exchange:
    796       // that never cashouts.  Registering these accounts can
    797       // be done via the access API.
    798       cashout_payto_uri?: string;
    799 
    800       // Is this account visible to anyone?
    801       is_public: boolean;
    802 
    803       // Is this a taler exchange account?
    804       is_taler_exchange: boolean;
    805 
    806       // Is the account locked.
    807       // Defaults to false.
    808       // @deprecated since **v7**
    809       is_locked?: boolean;
    810 
    811       // @deprecated in **v10**
    812       // Is 2FA enabled and what channel is used for challenges?
    813       tan_channel?: TanChannel;
    814 
    815       // Is 2FA enabled and what channels are used for challenges?
    816       // @since **v10**
    817       tan_channels?: TanChannel[];
    818 
    819       // Current status of the account
    820       // active: the account can be used
    821       // locked: the account can be used but cannot create new tokens
    822       // @since **v7**
    823       // deleted: the account has been deleted but is retained for compliance
    824       // reasons, only the administrator can access it
    825       // Defaults to 'active' is missing
    826       // @since **v4**, will become mandatory in the next version.
    827       status?: "active" | "locked" | "deleted";
    828 
    829       // Conversion rate class of the user
    830       // Only present if conversion is activated on the server
    831       // @since **v9**
    832       conversion_rate_class_id?: Integer;
    833     }
    834 
    835 Transactions
    836 ------------
    837 
    838 .. http:get:: /accounts/$USERNAME/transactions
    839 
    840   Retrieve a subset of transactions related to $USERNAME.
    841 
    842   **Request:**
    843 
    844   :query limit: *Optional.*
    845     At most return the given number of results. Negative for descending by ``row_id``, positive for ascending by ``row_id``. Defaults to ``-20``. Since **v5**.
    846   :query offset: *Optional.*
    847     Starting ``row_id`` for :ref:`pagination <row-id-pagination>`. Since **v5**.
    848   :query timeout_ms: *Optional.*
    849     Timeout in milliseconds, for :ref:`long-polling <long-polling>`, to wait for at least one element to be shown. Only useful if *limit* is positive. Since protocol **v5**.
    850   :query delta: *Optional.*
    851     Deprecated since **v5**. Use *limit* instead.
    852   :query start: *Optional.*
    853     Deprecated since **v5**. Use *offset* instead.
    854   :query long_poll_ms: *Optional.*
    855     Deprecated since **v5**. Use *timeout_ms* instead.
    856 
    857   **Response:**
    858 
    859   :http:statuscode:`200 OK`:
    860     The bank responds with an `BankAccountTransactionsResponse` object.
    861   :http:statuscode:`204 No content`:
    862     No transaction found.
    863   :http:statuscode:`401 Unauthorized`:
    864     Invalid or missing credentials.
    865   :http:statuscode:`403 Forbidden`:
    866     Missing rights.
    867   :http:statuscode:`404 Not found`:
    868     The account pointed by ``$USERNAME`` was not found.
    869 
    870   **Details:**
    871 
    872   .. ts:def:: BankAccountTransactionsResponse
    873 
    874     interface BankAccountTransactionsResponse {
    875       transactions: BankAccountTransactionInfo[];
    876     }
    877 
    878 .. http:get:: /accounts/$USERNAME/transactions/$TRANSACTION_ID
    879 
    880   Retrieve the transaction whose identifier is ``TRANSACTION_ID``.
    881 
    882   **Response:**
    883 
    884   :http:statuscode:`200 OK`:
    885     The bank responds with an `BankAccountTransactionInfo` object.
    886   :http:statuscode:`401 Unauthorized`:
    887     Invalid or missing credentials.
    888   :http:statuscode:`403 Forbidden`:
    889     Missing rights.
    890   :http:statuscode:`404 Not found`:
    891     The account pointed by ``$USERNAME`` was not found.
    892 
    893   **Details:**
    894 
    895   .. ts:def:: BankAccountTransactionInfo
    896 
    897     interface BankAccountTransactionInfo {
    898       // Full payto URI to identify the receiver of funds.
    899       creditor_payto_uri: string;
    900 
    901       // Full payto URI to identify the sender of funds.
    902       debtor_payto_uri: string;
    903 
    904       // Amount received.
    905       amount: Amount;
    906 
    907       // The direction of the transaction relative to $USERNAME account.
    908       // debit: $USERNAME is the debtor
    909       // credit: $USERNAME is the creditor
    910       direction: "debit" | "credit";
    911 
    912       // The wire transfer subjec
    913       subject: string;
    914 
    915       // Transaction unique ID.  Matches
    916       // $TRANSACTION_ID from the URI.
    917       row_id: Integer;
    918 
    919       // Date of the transaction.
    920       date: Timestamp;
    921     }
    922 
    923 .. http:post:: /accounts/$USERNAME/transactions
    924 
    925   Create a new transaction where the bank account with the label ``USERNAME`` is **debited**.
    926 
    927   **Request:**
    928 
    929   .. ts:def:: CreateTransactionRequest
    930 
    931     interface CreateTransactionRequest {
    932       // Address in the payto format of the wire transfer receiver.
    933       // It needs at least the 'message' query string parameter.
    934       payto_uri: string;
    935 
    936       // Transaction amount (in the $currency:x.y format), optional.
    937       // However, when not given, its value must occupy the 'amount'
    938       // query string parameter of the 'payto' field.  In case it
    939       // is given in both places, the payto_uri's takes the precedence.
    940       amount: string;
    941 
    942       // Nonce to make the request idempotent.  Requests with the same
    943       // ``request_uid`` that differ in any of the other fields
    944       // are rejected.
    945       // @since **v4**, will become mandatory in the next version.
    946       request_uid?: ShortHashCode;
    947     }
    948 
    949   **Response:**
    950 
    951   :http:statuscode:`200 Ok`:
    952     The bank responds with an `CreateTransactionResponse` object.
    953   :http:statuscode:`202 Accepted`:
    954     2FA is required for this operation. This returns the `ChallengeResponse` response. @since **v10**
    955   :http:statuscode:`400 Bad Request`:
    956     The request was invalid or the payto://-URI used unacceptable features.
    957   :http:statuscode:`401 Unauthorized`:
    958     Invalid or missing credentials.
    959   :http:statuscode:`403 Forbidden`:
    960     Missing rights.
    961   :http:statuscode:`404 Not found`:
    962     The account pointed by ``$USERNAME`` was not found.
    963   :http:statuscode:`409 Conflict`:
    964     * ``TALER_EC_BANK_SAME_ACCOUNT`` : creditor account is the same than ``USERNAME``.
    965     * ``TALER_EC_BANK_UNKNOWN_CREDITOR`` : creditor account was not found.
    966     * ``TALER_EC_BANK_UNALLOWED_DEBIT`` : the account does not have sufficient funds or the amount is too low or too high.
    967     * ``TALER_EC_BANK_TRANSFER_REQUEST_UID_REUSED``: an operation with the same ``request_uid`` but different details has been submitted before.
    968 
    969   **Details:**
    970 
    971   .. ts:def:: CreateTransactionResponse
    972 
    973     interface CreateTransactionResponse {
    974       // ID identifying the transaction being created
    975       row_id: Integer;
    976     }
    977 
    978 Account withdrawals
    979 -------------------
    980 
    981 .. http:post:: /accounts/$USERNAME/withdrawals
    982 
    983   Create a withdrawal operation, resulting in a ``taler://withdraw`` URI.
    984 
    985   **Request:**
    986 
    987   The request must be a `BankAccountCreateWithdrawalRequest`.
    988 
    989   **Response:**
    990 
    991   :http:statuscode:`200 Ok`:
    992     The bank responds with an `BankAccountCreateWithdrawalResponse` object.
    993   :http:statuscode:`401 Unauthorized`:
    994     Invalid or missing credentials.
    995   :http:statuscode:`403 Forbidden`:
    996     Missing rights.
    997   :http:statuscode:`404 Not found`:
    998     The account pointed by ``$USERNAME`` was not found.
    999   :http:statuscode:`409 Conflict`:
   1000     The account does not have sufficient funds.
   1001 
   1002   **Details:**
   1003 
   1004   .. ts:def:: BankAccountCreateWithdrawalRequest
   1005 
   1006     interface BankAccountCreateWithdrawalRequest {
   1007       // Amount to withdraw.  If given, the wallet
   1008       // cannot change the amount.
   1009       // Optional since **v6**.
   1010       amount?: Amount;
   1011 
   1012       // Suggested amount to withdraw. The wallet can
   1013       // still change the suggestion.
   1014       // @since **v6**
   1015       suggested_amount?: Amount;
   1016 
   1017       // If true, tell the wallet not to allow the user to
   1018       // specify an amount to withdraw and to not provide
   1019       // any amount when registering with the withdrawal
   1020       // operation. The amount to withdraw will be set
   1021       // by the final ``/withdrawals/$WITHDRAWAL_ID/confirm`` step.
   1022       // @since **v8**
   1023       no_amount_to_wallet?: boolean;
   1024     }
   1025 
   1026   .. ts:def:: BankAccountCreateWithdrawalResponse
   1027 
   1028     interface BankAccountCreateWithdrawalResponse {
   1029       // ID identifying the operation being created
   1030       withdrawal_id: string;
   1031 
   1032       // URI that can be passed to the wallet to initiate the withdrawal
   1033       taler_withdraw_uri: string;
   1034     }
   1035 
   1036 .. http:post:: /accounts/$USERNAME/withdrawals/$WITHDRAWAL_ID/confirm
   1037 
   1038   Confirms ``WITHDRAWAL_ID`` operation.  Has no effect on an already confirmed
   1039   withdrawal operation.  This call is responsible for wiring the funds to the
   1040   exchange.
   1041 
   1042   **Request:**
   1043 
   1044   .. ts:def:: BankAccountConfirmWithdrawalRequest
   1045 
   1046     interface BankAccountConfirmWithdrawalRequest {
   1047 
   1048       // Selected amount to be transferred. Optional if the
   1049       // backend already knows the amount.
   1050       // @since **v6**
   1051       amount?: Amount;
   1052     }
   1053 
   1054 
   1055   **Response:**
   1056 
   1057   :http:statuscode:`202 Accepted`:
   1058     2FA is required for this operation. This returns the `ChallengeResponse` response. @since **v10**
   1059   :http:statuscode:`204 No content`:
   1060     The withdrawal operation has been confirmed.
   1061   :http:statuscode:`401 Unauthorized`:
   1062     Invalid or missing credentials.
   1063   :http:statuscode:`403 Forbidden`:
   1064     Missing rights.
   1065   :http:statuscode:`404 Not found`:
   1066     The operation was not found.
   1067   :http:statuscode:`409 Conflict`:
   1068     * ``TALER_EC_BANK_CONFIRM_ABORT_CONFLICT`` : the withdrawal has been aborted previously and can't be confirmed.
   1069     * ``TALER_EC_BANK_CONFIRM_INCOMPLETE`` : the withdraw operation cannot be confirmed because no exchange and reserve public key selection happened before.
   1070     * ``TALER_EC_BANK_DUPLICATE_RESERVE_PUB_SUBJECT``: the reserve public key is already used.
   1071     * ``TALER_EC_BANK_UNALLOWED_DEBIT`` : the account does not have sufficient funds or the amount is too low or too high
   1072     * ``TALER_EC_BANK_AMOUNT_DIFFERS`` : the specified amount will not work for this withdrawal (since **v6**).
   1073     * ``TALER_EC_BANK_AMOUNT_REQUIRED`` : the backend requires an amount to be specified  (since **v6**).
   1074 
   1075 .. http:post:: /accounts/$USERNAME/withdrawals/$WITHDRAWAL_ID/abort
   1076 
   1077   Aborts ``WITHDRAWAL_ID`` operation.  Has no effect on an already aborted
   1078   operation.
   1079 
   1080   **Response:**
   1081 
   1082   :http:statuscode:`204 No content`:
   1083     The withdrawal operation has been aborted.
   1084   :http:statuscode:`401 Unauthorized`:
   1085     Invalid or missing credentials.
   1086   :http:statuscode:`403 Forbidden`:
   1087     Missing rights.
   1088   :http:statuscode:`404 Not found`:
   1089     The withdrawal operation was not found.
   1090   :http:statuscode:`409 Conflict`:
   1091     The withdrawal operation has been confirmed previously and can't be aborted.
   1092 
   1093 .. http:get:: /withdrawals/$WITHDRAWAL_ID
   1094 
   1095   Retrieve public information about ``WITHDRAWAL_ID`` withdrawal operation.
   1096   Does not require further authentication as knowledge of ``WITHDRAWAL_ID``
   1097   serves as an authenticator.
   1098 
   1099   **Request:**
   1100 
   1101   :query old_state:
   1102     *Optional.* Defaults to "pending".
   1103   :query timeout_ms: *Optional.*
   1104     Timeout in milliseconds, for :ref:`long-polling <long-polling>`, to wait for the operation state to be different from *old_state*. Since **v5**.
   1105   :query long_poll_ms: *Optional.*
   1106     Deprecated since **v5.** Use *timeout_ms* instead.
   1107 
   1108   **Response:**
   1109 
   1110   :http:statuscode:`200 Ok`:
   1111     The bank responds with an `WithdrawalPublicInfo` object.
   1112   :http:statuscode:`404 Not found`:
   1113     The operation was not found.
   1114 
   1115   **Details:**
   1116 
   1117   .. ts:def:: WithdrawalPublicInfo
   1118 
   1119     interface WithdrawalPublicInfo {
   1120       // Current status of the operation
   1121       // pending: the operation is pending parameters selection (exchange and reserve public key)
   1122       // selected: the operations has been selected and is pending confirmation
   1123       // aborted: the operation has been aborted
   1124       // confirmed: the transfer has been confirmed and registered by the bank
   1125       status: "pending" | "selected" | "aborted" | "confirmed";
   1126 
   1127       // Amount that will be withdrawn with this operation
   1128       // (raw amount without fee considerations).  Only
   1129       // given once the amount is fixed and cannot be changed.
   1130       // Optional since **v6**.
   1131       amount?: Amount;
   1132 
   1133       // Suggestion for the amount to be withdrawn with this
   1134       // operation.  Given if a suggestion was made but the
   1135       // user may still change the amount.
   1136       // Optional since **v6**.
   1137       suggested_amount?: Amount;
   1138 
   1139       // If true, the wallet must not allow the user to
   1140       // specify an amount to withdraw and to not provide
   1141       // any amount when registering with the withdrawal
   1142       // operation. The amount to withdraw will be set
   1143       // by the final ``/withdrawals/$WITHDRAWAL_ID/confirm`` step.
   1144       // @since **v8**
   1145       no_amount_to_wallet?: boolean;
   1146 
   1147       // Account username
   1148       username: string;
   1149 
   1150       // Reserve public key selected by the exchange,
   1151       // only non-null if ``status`` is ``selected`` or ``confirmed``.
   1152       selected_reserve_pub?: string;
   1153 
   1154       // Exchange account selected by the wallet
   1155       // only non-null if ``status`` is ``selected`` or ``confirmed``.
   1156       selected_exchange_account?: string;
   1157     }
   1158 
   1159 Cashouts
   1160 --------
   1161 
   1162 .. _account-cashout:
   1163 
   1164 .. http:post:: /accounts/$USERNAME/cashouts
   1165 
   1166   Initiates a conversion to fiat currency.  The fiat
   1167   bank account to be
   1168   credited is the one specified at registration time via the
   1169   *cashout_payto_uri* parameter.  The regional bank account
   1170   is specified via ``$USERNAME``.
   1171 
   1172   .. note::
   1173 
   1174     Consult the `cashout rates call <cashout-rates_>`_ to learn
   1175     about any applicable fee or exchange rate.
   1176 
   1177 
   1178   **Request:**
   1179 
   1180   .. ts:def:: CashoutRequest
   1181 
   1182     interface CashoutRequest {
   1183       // Nonce to make the request idempotent.  Requests with the same
   1184       // ``request_uid`` that differ in any of the other fields
   1185       // are rejected.
   1186       request_uid: ShortHashCode;
   1187 
   1188       // Optional subject to associate to the
   1189       // cashout operation.  This data will appear
   1190       // as the incoming wire transfer subject in
   1191       // the user's fiat bank account.
   1192       subject?: string;
   1193 
   1194       // That is the plain amount that the user specified
   1195       // to cashout.  Its $currency is the (regional) currency of the
   1196       // bank instance.
   1197       amount_debit: Amount;
   1198 
   1199       // That is the amount that will effectively be
   1200       // transferred by the bank to the user's fiat bank
   1201       // account.
   1202       // It is expressed in the fiat currency and
   1203       // is calculated after the cashout fee and the
   1204       // exchange rate.  See the /cashout-rate call.
   1205       // The client needs to calculate this amount
   1206       // correctly based on the amount_debit and the cashout rate,
   1207       // otherwise the request will fail.
   1208       amount_credit: Amount;
   1209     }
   1210 
   1211   **Response:**
   1212 
   1213   :http:statuscode:`200 OK`:
   1214     The cashout request was correctly created.
   1215     This returns the `CashoutResponse` response.
   1216   :http:statuscode:`202 Accepted`:
   1217     2FA is required for this operation. This returns the `ChallengeResponse` response. @since **v10**
   1218   :http:statuscode:`401 Unauthorized`:
   1219     Invalid or missing credentials.
   1220   :http:statuscode:`403 Forbidden`:
   1221     Missing rights.
   1222   :http:statuscode:`404 Not found`:
   1223     The account pointed by ``$USERNAME`` was not found.
   1224   :http:statuscode:`409 Conflict`:
   1225     * ``TALER_EC_BANK_TRANSFER_REQUEST_UID_REUSED``: an operation with the same ``request_uid`` but different details has been submitted before.
   1226     * ``TALER_EC_BANK_BAD_CONVERSION``: exchange rate was calculated incorrectly by the client.
   1227     * ``TALER_EC_BANK_BANK_CONVERSION_AMOUNT_TO_SMALL``: the amount of the cashout is too small.
   1228     * ``TALER_EC_BANK_UNALLOWED_DEBIT``: the account does not have sufficient funds or the amount is too low or too high.
   1229     * ``TALER_EC_BANK_CONFIRM_INCOMPLETE``: the user did not share any cashout payto to uri where to wire funds.
   1230   :http:statuscode:`501 Not Implemented`:
   1231     * ``TALER_EC_BANK_TAN_CHANNEL_NOT_SUPPORTED``: the chosen ``tan_channel`` or one of ``tan_channels`` is not currently supported.
   1232     * This server does not support conversion, client should check config response.
   1233 
   1234   **Details:**
   1235 
   1236   .. ts:def:: CashoutResponse
   1237 
   1238     interface CashoutResponse {
   1239       // ID identifying the operation being created
   1240       cashout_id: Integer;
   1241     }
   1242 
   1243 .. _circuit-cashout-details:
   1244 
   1245 .. http:get:: /accounts/$USERNAME/cashouts/$CASHOUT_ID
   1246 
   1247   Returns information about the status of the ``$CASHOUT_ID`` operation.
   1248   The request is available to the administrator and the account owner.
   1249 
   1250   **Response:**
   1251 
   1252   :http:statuscode:`200 OK`:
   1253     Response is a `CashoutStatusResponse`.
   1254   :http:statuscode:`401 Unauthorized`:
   1255     Invalid or missing credentials.
   1256   :http:statuscode:`403 Forbidden`:
   1257     Missing rights.
   1258   :http:statuscode:`404 Not found`:
   1259     The cashout operation was not found.
   1260   :http:statuscode:`501 Not implemented`:
   1261     This server does not support conversion, client should check config response.
   1262 
   1263   **Details:**
   1264 
   1265   .. ts:def:: CashoutStatusResponse
   1266 
   1267     interface CashoutStatusResponse {
   1268       // Amount debited to the regional bank account.
   1269       amount_debit: Amount;
   1270 
   1271       // Amount credited to the fiat bank account.
   1272       amount_credit: Amount;
   1273 
   1274       // Transaction subject.
   1275       subject: string;
   1276 
   1277       // Time when the cashout was created.
   1278       creation_time: Timestamp;
   1279     }
   1280 
   1281 .. _circuit-cashouts:
   1282 
   1283 .. http:get:: /accounts/$USERNAME/cashouts
   1284 
   1285   Returns the list of all cash-out operations for an account.
   1286 
   1287   **Request:**
   1288 
   1289   :query limit: *Optional.*
   1290     At most return the given number of results. Negative for descending by ``cashout_id``, positive for ascending by ``cashout_id``. Defaults to ``-20``. Since **v5**.
   1291   :query offset: *Optional.*
   1292     Starting ``cashout_id`` for :ref:`pagination <row-id-pagination>`. Since **v5**.
   1293   :query delta: *Optional.*
   1294     Deprecated since **v5**. Use *limit* instead.
   1295   :query start: *Optional.*
   1296     Deprecated since **v5**. Use *offset* instead.
   1297 
   1298   **Response:**
   1299 
   1300   :http:statuscode:`200 OK`:
   1301     Response is a `Cashouts`.
   1302   :http:statuscode:`204 No Content`:
   1303     No cash-out operations were found.
   1304   :http:statuscode:`401 Unauthorized`:
   1305     Invalid or missing credentials.
   1306   :http:statuscode:`403 Forbidden`:
   1307     Missing rights.
   1308   :http:statuscode:`501 Not implemented`:
   1309     This server does not support conversion, client should check config response.
   1310 
   1311   **Details:**
   1312 
   1313   .. ts:def:: Cashouts
   1314 
   1315     interface Cashouts {
   1316       // Every string represents a cash-out operation ID.
   1317       cashouts: CashoutInfo[];
   1318     }
   1319 
   1320   .. ts:def:: CashoutInfo
   1321 
   1322     interface CashoutInfo {
   1323       cashout_id: Integer;
   1324     }
   1325 
   1326 .. http:get:: /cashouts
   1327 
   1328   Returns the list of all cash-out operations for **all** accounts.
   1329 
   1330   Can only be used by the administrators.
   1331 
   1332   **Request:**
   1333 
   1334   :query limit: *Optional.*
   1335     At most return the given number of results. Negative for descending by ``cashout_id``, positive for ascending by ``cashout_id``. Defaults to ``-20``. Since **v5**.
   1336   :query offset: *Optional.*
   1337     Starting ``cashout_id`` for :ref:`pagination <row-id-pagination>`. Since **v5**.
   1338   :query delta: *Optional.*
   1339     Deprecated since **v5**. Use *limit* instead.
   1340   :query start: *Optional.*
   1341     Deprecated since **v5**. Use *offset* instead.
   1342 
   1343   .. note::
   1344 
   1345     We might want to add a filter in the future to only
   1346     query pending cashout operations.
   1347 
   1348   **Response:**
   1349 
   1350   :http:statuscode:`200 OK`:
   1351     Response is a `GlobalCashouts`.
   1352   :http:statuscode:`204 No Content`:
   1353     No cash-out operations were found.
   1354   :http:statuscode:`401 Unauthorized`:
   1355     Invalid or missing credentials.
   1356   :http:statuscode:`403 Forbidden`:
   1357     Missing rights.
   1358   :http:statuscode:`501 Not implemented`:
   1359     This server does not support conversion, client should check config response.
   1360 
   1361   **Details:**
   1362 
   1363   .. ts:def:: GlobalCashouts
   1364 
   1365     interface GlobalCashouts {
   1366       cashouts: GlobalCashoutInfo[];
   1367     }
   1368 
   1369   .. ts:def:: GlobalCashoutInfo
   1370 
   1371     interface GlobalCashoutInfo {
   1372       cashout_id: Integer;
   1373       username: string;
   1374     }
   1375 
   1376 Conversion rate class
   1377 ---------------------
   1378 
   1379 .. http:post:: /conversion-rate-classes
   1380 
   1381   Create a new conversion rate classe.
   1382 
   1383   Only available to the administrator.
   1384 
   1385   Since protocol **v9**.
   1386 
   1387   **Request:**
   1388 
   1389   .. ts:def:: ConversionRateClassInput
   1390 
   1391     interface ConversionRateClassInput {
   1392       // The name of this class
   1393       name: string;
   1394 
   1395       // A description of the class
   1396       description?: string;
   1397 
   1398       // Minimum fiat amount authorised for cashin before conversion
   1399       cashin_min_amount?: Amount;
   1400 
   1401       // Exchange rate to buy regional currency from fiat
   1402       cashin_ratio?: DecimalNumber;
   1403 
   1404       // Regional amount fee to subtract after applying the cashin ratio.
   1405       cashin_fee?: Amount;
   1406 
   1407       // Rounding mode used during cashin conversion
   1408       cashin_rounding_mode?: "zero" | "up" | "nearest";
   1409 
   1410       // Minimum regional amount authorised for cashout before conversion
   1411       cashout_min_amount?: Amount;
   1412 
   1413       // Exchange rate to sell regional currency for fiat
   1414       cashout_ratio?: DecimalNumber;
   1415 
   1416       // Fiat amount fee to subtract after applying the cashout ratio.
   1417       cashout_fee?: Amount;
   1418 
   1419       // Rounding mode used during cashout conversion
   1420       cashout_rounding_mode?: "zero" | "up" | "nearest";
   1421     }
   1422 
   1423   **Response:**
   1424 
   1425   :http:statuscode:`200 OK`:
   1426     The conversion rate class request was correctly created.
   1427     This returns the `ConversionRateClassResponse` response.
   1428   :http:statuscode:`401 Unauthorized`:
   1429     Invalid or missing credentials.
   1430   :http:statuscode:`403 Forbidden`:
   1431     Missing rights.
   1432   :http:statuscode:`409 Conflict`:
   1433     * ``TALER_EC_BANK_NAME_REUSE`` : name already used.
   1434   :http:statuscode:`501 Not implemented`:
   1435     This server does not support conversion, client should check config response.
   1436 
   1437   **Details:**
   1438 
   1439   .. ts:def:: ConversionRateClassResponse
   1440 
   1441     interface ConversionRateClassResponse {
   1442       // ID identifying the conversion rate class being created
   1443       conversion_rate_class_id: Integer;
   1444     }
   1445 
   1446 .. http:patch:: /conversion-rate-classes/{CLASS_ID}
   1447 
   1448   Edit an existing conversion rate class.
   1449 
   1450   Only available to the administrator.
   1451 
   1452   Since protocol **v9**.
   1453 
   1454   **Request:**
   1455 
   1456   `ConversionRateClassInput`
   1457 
   1458   **Response:**
   1459 
   1460   :http:statuscode:`204 No Content`:
   1461     The conversion rate class request was correctly edited.
   1462   :http:statuscode:`401 Unauthorized`:
   1463     Invalid or missing credentials.
   1464   :http:statuscode:`403 Forbidden`:
   1465     Missing rights.
   1466   :http:statuscode:`404 Not Found`:
   1467     The conversion rate class was not found.
   1468   :http:statuscode:`409 Conflict`:
   1469     * ``TALER_EC_BANK_NAME_REUSE`` : name already used.
   1470   :http:statuscode:`501 Not implemented`:
   1471     This server does not support conversion, client should check config response.
   1472 
   1473 .. http:delete:: /conversion-rate-classes/{CLASS_ID}
   1474 
   1475   Delete an existing conversion rate class.
   1476 
   1477   Only available to the administrator.
   1478 
   1479   Since protocol **v9**.
   1480 
   1481   **Response:**
   1482 
   1483   :http:statuscode:`204 No Content`:
   1484     The conversion rate class request was correctly deleted.
   1485   :http:statuscode:`401 Unauthorized`:
   1486     Invalid or missing credentials.
   1487   :http:statuscode:`403 Forbidden`:
   1488     Missing rights.
   1489   :http:statuscode:`404 Not Found`:
   1490     The conversion rate class was not found.
   1491   :http:statuscode:`409 Conflict`:
   1492     * ``TODO_LINKED_ACCOUNT`` : some accounts belongs to this class.
   1493   :http:statuscode:`501 Not implemented`:
   1494     This server does not support conversion, client should check config response.
   1495 
   1496 .. http:get:: /conversion-rate-classes/{CLASS_ID}
   1497 
   1498   Get an existing conversion rate class.
   1499 
   1500   Only available to the administrator.
   1501 
   1502   Since protocol **v9**.
   1503 
   1504   **Response:**
   1505 
   1506   :http:statuscode:`200 OK`:
   1507     Response is a `ConversionRateClass`.
   1508   :http:statuscode:`401 Unauthorized`:
   1509     Invalid or missing credentials.
   1510   :http:statuscode:`403 Forbidden`:
   1511     Missing rights.
   1512   :http:statuscode:`404 Not Found`:
   1513     The conversion rate class was not found.
   1514   :http:statuscode:`501 Not implemented`:
   1515     This server does not support conversion, client should check config response.
   1516 
   1517   **Details:**
   1518 
   1519   .. ts:def:: ConversionRateClassResponse
   1520 
   1521     interface ConversionRateClass {
   1522       // The name of this class
   1523       name: string;
   1524 
   1525       // A description of the class
   1526       description?: string;
   1527 
   1528       // Class unique ID
   1529       conversion_rate_class_id: Integer;
   1530 
   1531       // Number of users affected to this class
   1532       num_users: Integer;
   1533 
   1534       // Minimum fiat amount authorised for cashin before conversion
   1535       cashin_min_amount?: Amount;
   1536 
   1537       // Exchange rate to buy regional currency from fiat
   1538       cashin_ratio?: DecimalNumber;
   1539 
   1540       // Regional amount fee to subtract after applying the cashin ratio.
   1541       cashin_fee?: Amount;
   1542 
   1543       // Rounding mode used during cashin conversion
   1544       cashin_rounding_mode?: "zero" | "up" | "nearest";
   1545 
   1546       // Minimum regional amount authorised for cashout before conversion
   1547       cashout_min_amount?: Amount;
   1548 
   1549       // Exchange rate to sell regional currency for fiat
   1550       cashout_ratio?: DecimalNumber;
   1551 
   1552       // Fiat amount fee to subtract after applying the cashout ratio.
   1553       cashout_fee?: Amount;
   1554 
   1555       // Rounding mode used during cashout conversion
   1556       cashout_rounding_mode?: "zero" | "up" | "nearest";
   1557     }
   1558 
   1559 .. http:get:: /conversion-rate-classes
   1560 
   1561   Returns the list of all conversion rate classes.
   1562 
   1563   Only available to the administrator.
   1564 
   1565   Since protocol **v9**.
   1566 
   1567   **Request:**
   1568 
   1569   :query limit: *Optional.*
   1570     At most return the given number of results. Negative for descending by ``conversion_rate_class_id``, positive for ascending by ``conversion_rate_class_id``. Defaults to ``-20``.
   1571   :query offset: *Optional.*
   1572     Starting ``conversion_rate_class_id`` for :ref:`pagination <row-id-pagination>`.
   1573   :query filter_name: *Optional.*
   1574     Pattern to filter on the class name.  Given
   1575     the filter 'foo', all the classes will **contain**
   1576     'foo' in their name.  Without this option,
   1577     all the existing classes are returned.
   1578 
   1579   **Response:**
   1580 
   1581   :http:statuscode:`200 OK`:
   1582     Response is a `ConversionRateClasses`.
   1583   :http:statuscode:`401 Unauthorized`:
   1584     Invalid or missing credentials.
   1585   :http:statuscode:`403 Forbidden`:
   1586     Missing rights.
   1587   :http:statuscode:`404 Not Found`:
   1588     The conversion rate class was not found.
   1589   :http:statuscode:`501 Not implemented`:
   1590     This server does not support conversion, client should check config response.
   1591 
   1592   **Details:**
   1593 
   1594   .. ts:def:: ConversionRateClasses
   1595 
   1596     interface ConversionRateClasses {
   1597       classes: ConversionRateClass[];
   1598     }
   1599 
   1600 
   1601 Two Factor Auth
   1602 ---------------
   1603 
   1604 202 Challenge Responses
   1605 ^^^^^^^^^^^^^^^^^^^^^^^
   1606 
   1607 Various APIs generate ``202 Accepted`` HTTP status codes when multi-factor
   1608 authentication (MFA) is required.  In this case, the response will be a
   1609 `ChallengeResponse`.  In these cases, the client must first request and solve
   1610 one or more challenges before repeating the request. When repeating the
   1611 request, they must include a list of comma-separated challenge IDs of the
   1612 solved challenges in an ``Taler-Challenge-Ids`` HTTP header. The body must
   1613 remain absolutely unchanged.
   1614 
   1615 .. note::
   1616 
   1617   If all allowed attempts to solve the MFA challenge(s) fail, the endpoint
   1618   may start to return ``403 Forbidden`` until the issued challenges expire,
   1619   preventing the request from being completed for a while.  In this case,
   1620   repeating the request with a different body may still be allowed!
   1621 
   1622 .. ts:def:: ChallengeResponse
   1623 
   1624   // @since v10
   1625   interface ChallengeResponse {
   1626     // List of challenge IDs that must be solved before the
   1627     // client may proceed.
   1628     challenges: Challenge[];
   1629 
   1630     // True if **all** challenges must be solved (AND), false if
   1631     // it is sufficient to solve one of them (OR).
   1632     combi_and: boolean;
   1633   }
   1634 
   1635 .. ts:def:: Challenge
   1636 
   1637   // @since v10
   1638   interface Challenge {
   1639     // Unique identifier of the challenge to solve to run this protected
   1640     // operation.
   1641     challenge_id: string;
   1642 
   1643     // Channel that will be used to transmit the challenge.
   1644     tan_channel: TanChannel;
   1645 
   1646     // Hint to show to the user as to where the challenge will be
   1647     // sent or what to use to solve the challenge. May not
   1648     // contain the full address for privacy.
   1649     tan_info: string;
   1650   }
   1651 
   1652 .. ts:def:: TanChannel
   1653 
   1654   enum TanChannel {
   1655     SMS = "sms",
   1656     EMAIL = "email"
   1657   }
   1658 
   1659 Requesting challenges
   1660 ^^^^^^^^^^^^^^^^^^^^^
   1661 
   1662 .. http:post:: /accounts/$USERNAME/challenge/$CHALLENGE_ID
   1663 
   1664   Send TAN code for the ``CHALLENGE_ID`` challenge.
   1665 
   1666   This request can be posted several times to trigger TAN retransmission when the current code has expired or too many confirmation attempts have been made.
   1667 
   1668   This endpoint is not authenticated. @since **v10**
   1669 
   1670   **Request:**
   1671 
   1672   The request body must be empty.
   1673 
   1674   **Response:**
   1675 
   1676   :http:statuscode:`200 Ok`:
   1677     The TAN code has been sent. The body will be a `ChallengeRequestResponse`.
   1678   :http:statuscode:`404 Not Found`:
   1679     * ``TALER_EC_BANK_TAN_CHANNEL_SCRIPT_FAILED``: TAN transmition failed.
   1680     * ``TALER_EC_BANK_TAN_CHALLENGE_EXPIRED``: TAN transmition failed.
   1681       The challenge was not found.
   1682   :http:statuscode:`410 Gone`:
   1683     The challenge was already solved.
   1684   :http:statuscode:`429 Too many requests`:
   1685     Too many challenges are active right now, you must wait or confirm current challenges.
   1686   :http:statuscode:`502 Bad Gateway`:
   1687     * ``TALER_EC_BANK_TAN_CHANNEL_SCRIPT_FAILED``: TAN transmition failed.
   1688 
   1689   **Details:**
   1690 
   1691   .. ts:def:: ChallengeRequestResponse
   1692 
   1693     interface ChallengeRequestResponse {
   1694       // How long does the client have to solve the
   1695       // challenge.
   1696       solve_expiration: Timestamp;
   1697 
   1698       // What is the earlist time at which the client
   1699       // may request a new challenge to be transmitted?
   1700       earliest_retransmission: Timestamp;
   1701     }
   1702 
   1703 Solving challenges
   1704 ^^^^^^^^^^^^^^^^^^
   1705 
   1706 .. http:post:: /accounts/$USERNAME/challenge/$CHALLENGE_ID/confirm
   1707 
   1708   Solves the ``CHALLENGE_ID`` challenge and allows performing the protected operation.
   1709 
   1710   When the challenge is confirmed, you can call the protected endpoint again with ``CHALLENGE_ID`` in the ``Taler-Challenge-Ids`` HTTP header and an the original request body.
   1711 
   1712   This endpoints is not authenticated. Too many unsuccessful attempts to confirm token creation challenges block the account.
   1713 
   1714   **Request:**
   1715 
   1716   .. ts:def:: ChallengeSolve
   1717 
   1718     interface ChallengeSolve {
   1719       // The TAN code that solves $CHALLENGE_ID
   1720       tan: string;
   1721     }
   1722 
   1723   **Response:**
   1724 
   1725   :http:statuscode:`204 No Content`:
   1726     The challenge is confirmed.
   1727   :http:statuscode:`404 Not Found`:
   1728     * ``TALER_EC_BANK_TRANSACTION_NOT_FOUND`` : unknown challenge TAN.
   1729     * ``TALER_EC_BANK_TAN_CHALLENGE_EXPIRED`` : expired challenge.
   1730   :http:statuscode:`409 Conflict`:
   1731     * ``TALER_EC_BANK_TAN_CHALLENGE_FAILED`` : wrong TAN.
   1732     * ``TALER_EC_BANK_TAN_CHALLENGE_EXPIRED`` : expired TAN.
   1733   :http:statuscode:`429 Too many requests`:
   1734     Too many failed confirmation attempts, a new TAN must be requested.
   1735 
   1736 
   1737 Monitor
   1738 -------
   1739 
   1740 .. http:get:: /monitor
   1741 
   1742   When the bank provides conversion between the local currency and an
   1743   external one, this call lets the bank administrator monitor the cashin
   1744   and cashout operations that were made from and to the external currency.
   1745   It shows as well figures related to internal payments made by a Taler
   1746   exchange component to internal bank accounts. Timeframes are in UTC.
   1747 
   1748   **Request:**
   1749 
   1750   :query timeframe: *Optional*.
   1751     This parameter admits one of the following values. Defaults to 'hour'.
   1752 
   1753     * hour
   1754     * day
   1755     * month
   1756     * year
   1757 
   1758   :query date_s: *Optional*.
   1759     Non-negative date in seconds after the UNIX Epoch. Defaults to current time.
   1760     @since **v4**
   1761 
   1762   :query which: *Optional*.
   1763     This parameter points at a particular element of the *timeframe* parameter.
   1764     Following are the admitted values for each one.
   1765     Defaults to the last snapshot taken of the *timeframe* parameter.
   1766     @deprecated since **v4**
   1767 
   1768     * hour: from 00 to 23
   1769     * day: from 1 to the last day of the current month.
   1770     * month: from 1 to 12
   1771     * year: Gregorian year in the YYYY format.
   1772 
   1773   **Response:**
   1774 
   1775   :http:statuscode:`200 OK`:
   1776     The bank responds with `MonitorResponse`.
   1777   :http:statuscode:`400 Bad Request`:
   1778     This error may indicate that the *which* parameter is not appropriate for the selected *timeframe*.  For example, timeframe=month and which=20 would result in this error.
   1779   :http:statuscode:`401 Unauthorized`:
   1780     Invalid or missing credentials.
   1781   :http:statuscode:`403 Forbidden`:
   1782     Missing rights.
   1783 
   1784   **Details:**
   1785 
   1786   .. note::
   1787 
   1788     API consumers may combine the values in the response with other
   1789     factors to serve different views to their users.
   1790 
   1791   .. ts:def:: MonitorResponse
   1792 
   1793     // Union discriminated by the "type" field.
   1794     type MonitorResponse =
   1795       | MonitorNoConversion
   1796       | MonitorWithConversion;
   1797 
   1798   .. ts:def:: MonitorNoConversion
   1799 
   1800     // Monitoring stats when conversion is not supported
   1801     interface MonitorNoConversion {
   1802       type: "no-conversions";
   1803 
   1804       // How many payments were made to a Taler exchange by another
   1805       // bank account.
   1806       talerInCount: Integer;
   1807 
   1808       // Overall volume that has been paid to a Taler
   1809       // exchange by another bank account.
   1810       talerInVolume: Amount;
   1811 
   1812       // How many payments were made by a Taler exchange to another
   1813       // bank account.
   1814       talerOutCount: Integer;
   1815 
   1816       // Overall volume that has been paid by a Taler
   1817       // exchange to another bank account.
   1818       talerOutVolume: Amount;
   1819     }
   1820 
   1821   .. ts:def:: MonitorWithConversion
   1822 
   1823     // Monitoring stats when conversion is supported
   1824     interface MonitorWithConversion {
   1825       type: "with-conversions";
   1826 
   1827       // How many cashin operations were confirmed by a
   1828       // wallet owner. Note: wallet owners
   1829       // are NOT required to be customers of the libeufin-bank.
   1830       cashinCount: Integer;
   1831 
   1832       // Overall regional currency that has been paid by the regional admin account
   1833       // to regional bank accounts to fulfill all the confirmed cashin operations.
   1834       cashinRegionalVolume: Amount;
   1835 
   1836       // Overall fiat currency that has been paid to the fiat admin account
   1837       // by fiat bank accounts to fulfill all the confirmed cashin operations.
   1838       cashinFiatVolume: Amount;
   1839 
   1840       // How many cashout operations were confirmed.
   1841       cashoutCount: Integer;
   1842 
   1843       // Overall regional currency that has been paid to the regional admin account
   1844       // by fiat bank accounts to fulfill all the confirmed cashout operations.
   1845       cashoutRegionalVolume: Amount;
   1846 
   1847       // Overall fiat currency that has been paid by the fiat admin account
   1848       // to fiat bank accounts to fulfill all the confirmed cashout operations.
   1849       cashoutFiatVolume: Amount;
   1850 
   1851       // How many payments were made to a Taler exchange by another
   1852       // bank account.
   1853       talerInCount: Integer;
   1854 
   1855       // Overall volume that has been paid to a Taler
   1856       // exchange by another bank account.
   1857       talerInVolume: Amount;
   1858 
   1859       // How many payments were made by a Taler exchange to another
   1860       // bank account.
   1861       talerOutCount: Integer;
   1862 
   1863       // Overall volume that has been paid by a Taler
   1864       // exchange to another bank account.
   1865       talerOutVolume: Amount;
   1866     }
   1867 
   1868 
   1869 Endpoints for Integrated Sub-APIs
   1870 ---------------------------------
   1871 
   1872 .. http:any:: /taler-integration/*
   1873 
   1874   All endpoints under this prefix are specified by the.
   1875   :doc:`GNU Taler bank integration API </core/api-bank-integration>`.
   1876   This API handles the communication with Taler wallets.
   1877 
   1878 
   1879 .. http:any:: /accounts/$USERNAME/taler-wire-gateway/*
   1880 
   1881   All endpoints under this prefix are specified
   1882   by the :doc:`GNU Taler wire gateway API </core/api-bank-wire>`.
   1883 
   1884   The endpoints are only available for accounts configured with ``is_taler_exchange=true``.
   1885 
   1886 .. http:any:: /accounts/$USERNAME/taler-wire-transfer-gateway/*
   1887 
   1888   Since **v12**
   1889 
   1890   All endpoints under this prefix are specified
   1891   by the :doc:`GNU Taler wire transfer gateway API </core/api-bank-wire-transfer>`.
   1892 
   1893   The endpoints are only available for accounts configured with ``is_taler_exchange=true``.
   1894 
   1895 .. http:any:: /accounts/$USERNAME/taler-revenue/*
   1896 
   1897   All endpoints under this prefix are specified
   1898   by the :doc:`GNU Taler Revenue API </core/api-bank-revenue>`.
   1899 
   1900 .. http:any:: /accounts/$USERNAME/conversion-info/*
   1901 
   1902   User custom rates, public for accounts configured with ``is_taler_exchange=true`` else private. Since **v9**
   1903 
   1904   All endpoints under this prefix are specified
   1905   by the :doc:`GNU Taler Conversion Info API </core/api-bank-conversion-info>`.
   1906 
   1907 .. http:any:: /conversion-rate-classes/$CLASS_ID/conversion-info/*
   1908 
   1909   Conversion rate conversion infos, admin only. Since **v9**
   1910 
   1911   All endpoints under this prefix are specified
   1912   by the :doc:`GNU Taler Conversion Info API </core/api-bank-conversion-info>`.
   1913 
   1914 .. http:any:: /conversion-info/*
   1915 
   1916   Global conversion rate infos.
   1917 
   1918   All endpoints under this prefix are specified
   1919   by the :doc:`GNU Taler Conversion Info API </core/api-bank-conversion-info>`.
   1920 
   1921 .. http:any:: /taler-observability/*
   1922 
   1923   Since **v11**
   1924 
   1925   All endpoints under this prefix are specified
   1926   by the :doc:`GNU Taler Observability API </core/api-observability>`.