# Bank selection

Once you've successfully activated your Token.io user account, you're ready to start integrating our API. Before initiating a request to a Token.io-connected bank, you'll need to get the list of banks in the desired country that support the features you need to access — or, more specifically, the features your user is requesting, presuming the user is an authorized account holder with a Token.io-connected bank. The [GET /banks](../../api/reference/Banks-v1#operation/GatewayService.GetBanks) call filters the list of Token.io-connected banks based on your selection criteria with respect to bank location and bank-supported features.

See [Base URLs](../../integration-considerations/api-basics#Base) and [Common Request Headers](../../integration-considerations/api-basics#Common) for more information on structuring the [GET /banks](../../api/reference/Banks-v1#operation/GatewayService.GetBanks) request.

In the [GET /banks](../../api/reference/Banks-v1#operation/GatewayService.GetBanks) request, there are numerous filtering criteria you can add as parameters to narrow your query. Field descriptions and usage are shown in the [API definition](../../api/reference). You can request a list of all banks available to users in a specific country or countries supporting particular features. Then, upon identifying the bank(s) meeting your criteria, you can display the results for user selection. If no matches are found, you can display that result to the user, as well.

Hence, in response to a successful request — for example, `GET /banks?ids = ob-iron` — the payload returned in the response will take this format:

**APIv1 Sample Response to GET {{BASE_URL}}/banks?ids=iron**


```json
{
"banks": [
    {
     "bankGroup": "xyz-bank-group",
     "bic": "HLFXESMMXXX", // bank's BIC code
     "countries": ["FR","DE"],
     "credentialFields": [   // if populated, user credentials to be captured by TPP prior to request initiation
           {
            "description": "User authentication",
            "displayName": "Client ID",
            "id": "clientId",
            "options": ["SMS", "Phone Call"],
            "password": true //v1 only
     }],
     "id": "ob-iron", // Token.io bankId
     "name": "Iron Bank",
     "logoUri": "https://s3-us-west-2.amazonaws.com/tokenio-assets/1.0.0/logos/iron/iron_square.png",
     "fullLogoUri": "https://s3-us-west-2.amazonaws.com/tokenio-assets/1.0.0/logos/iron/iron_full.png",
     "fieldsFormatInformation": [{ // bank-dependent formats indicating allowable characters
               "name": "field name", // name of the field
               "path": "path", // field location in request payload
               "constraint": "^[A-Za-z0-9?:()./, u0027±s]*$" // regex indicating allowable characters
     }],
     "mandatory-fields": { //populated request fields required by this bank
         "pis" { // object.field names are bank-defined
              "debtor-account": true
              "debtor-name": true
              "beneficiary-name": true
         }
     "supportsInformation": true,
     "requiresOneStepPayment  : false.
     "supportsSendPayment": true,
     "supportsFundsConfirmation": true,
     "provider": "Token",
     "supportsScheduledPayment": true,
     "supportsStandingOrder": true,
     "supportsTransactionsDateFilter": false,
     "supportsReturnRefundAccount": true,
     "supportedTransferDestinationTypes": ["BIC", "FASTER_PAYMENTS", "SEPA"]
     "transactionHistoryLimit": -1,
   }],
   "paging": {
        "page": 1,
         "perPage": 200,
         "pageCount": 1
    }
}
```

in [GET /banks](../../api/reference/Banks-v1#operation/GatewayService.GetBanks), when a bank name has a special character, it requires JSON parsing to display correctly.

For example, in the name "Caja Rural de L'alcudia" the apostrophe should be parsed with "\u0027" as the unicode character ': "Caja Rural de L\u0027alcudia" .

[Mandatory fields](#Mandatory) are bank-dependent and are handled on a bank-by-bank basis, as discussed below.

### Search and sort

You can optionally perform additional internal filtering on the result set returned by Token.io before displaying the results to the user for final selection. When retrieving the list of banks for which search text is provided in a `GET /banks?field=search-string` call, an alphabetical sort, if specified in the call, is applied to the search results before they are returned to the caller. This makes applying additional sort criteria to the search results unnecessary.

### Mandatory fields

Some banks require the TPP to provide certain fields in the payment initiation request. These are referred to as Mandatory fields. The Mandatory fields are captured in the `mandatoryFields` object in the `banks` object within the [GET /banks](../../api/reference/Banks-v1#operation/GatewayService.GetBanks) response from Token.io. The `mandatoryFields` object contains the fields which must be populated by the TPP for the given bank to accept a payment initiation request, or request for account access. Only fields specifically required by the source bank, rather than fields more broadly required by all banks, will appear in `mandatoryFields`. Consequently, fields that are required for all banks (*e.g.*, `refId`) or which are always optional (*e.g.*, `description`) are not part of `mandatoryFields`.

As applicable, the `mandatoryFields` object is organized by service (*e.g.*, `pis`, `ais`) and “instrument” (*e.g.*, `transfer`, `standingOrder`, and so forth.). Each payment instrument is further organized according to the bank-adopted API standard — NextGenPSD2, PolishAPI, STET or CMA9 — for domestic and international transfers to create the following general structure:

For `transfer`:

- `DOMESTIC` – the payer (debtor) and the payee (creditor) country are the same
- `INTERNATIONAL` – the payer (debtor) and the payee (creditor) country are different.


When added within the `bank` object in [the response example above](#example-response), a particular bank's `mandatoryFields` might be populated like this:


```json
"mandatoryFields": {
    "transfer": {
        "domestic": {
            "fields": [
                        "transfer_body.instructions.transfer_destinations.customer_data.legal_names",
                        "transfer_body.instructions.source.bic",
                        "transfer_body.instructions.source.account_identifier"
           ],
            "stetFields": [
                        "transfer_body.instructions.metadata.provider_transfer_metadata.stet_transfer_                         metadata.beneficiary.creditor_agent"
            ],
            "polishApiFields": [
                        "transfer_body.instructions.metadata.provider_transfer_metadata.polish_api_                         transfer_metadata.delivery_mode"
            ]
        },
        "international" {
            "fields": ["transfer_body.instructions.transfer_destinations.customer_data.legal_names"],
            "stet_fields": [
                        "transfer_body.instructions.metadata.provider_transfer_metadata.stet_transfer_                        metadata.beneficiary.creditor_agent"
            ]}
    },
    "standing_order" {
        "domestic" {
            "fields": ["standing_order_body.instructions.transfer_destinations.customer_data.legal_names"]
            "stet_fields": ["standing_order_body.instructions.metadata.provider_standing_order_            metadata.stet_standing_order_metadata.beneficiary.creditor_agent"]
},
        "international" {
            "fields": ["standing_order_body.instructions.transfer_destinations.customer_data.legal_names"]
            "stet_fields": ["standing_order_body.instructions.metadata.provider_standing_order_metadata                                .stet_standing_order_metadata.beneficiary.creditor_agent"]
       }
    }
}
```

**If** `mandatoryFields` **are required for a bank in [GET /banks](../../api/reference/Banks-v1#operation/GatewayService.GetBanks), you must provide these fields within the initiation request**.
If the field is not provided by the TPP, then either Token.io or the bank may return an error as a result of the missing field.

### Debtor account validation

The requirement to specify the debtor account for a transfer is bank-dependent When required, the TPP needs to include the user’s bank account from which the payment amount is being debited in the `initiation.debtor` object. The type of account identifiers and required fields depend in the payment rail:

| Account Type | Field name |
|  --- | --- |
| SEPA | `iban` |
| SEPA Instant | `iban` |
| UK Domestic | `accountNumber ` and `sortCode` |
| EU Domestic Non Euro | `iban` (IBAN Accounts) or `bban` (BBAN or Clearing Accounts) |
| EU Domestic Non Euro Instant | `iban` (IBAN Accounts) or `bban` (BBAN or Clearing Accounts) |
| Elixir in Poland | `iban` (IBAN Accounts) or `accountNumber` (Polish domestic accounts) |
| Bankgiro payments in Sweden | `bankgiroNumber` |
| PlusGiro payments in Sweden | `plusgiroNumber` |


In addition to the Token.io platform's `bankId` and the bank's `bic` (BIC), the `source` also contains a `customerData` object identifying the payer's `legalNames` and `address` (see the [Token.io API definition](../../api/reference/Requests-for-Payments-v1-or-AIS#operation/GatewayService.StoreTokenRequest) for complete object-field specifications).

In accordance with the following rules, Token.io verifies the `source` in token requests to avoid preventable account identification errors during payment processing:

1. If a transfer token request has a non-empty `source` object, it must also have a populated `accountIdentifier`. Populating `customerData.legalNames` without identifying the bank account, for example, will throw an `InvalidArgument "Missing required field bank_account or account_identifier in source account"`error.
2. If the `accountIdentifier` object is populated, it must also have a populated identifier type; otherwise, an `InvalidArgument "Missing required field<field name>in source account"` error will result. Here, *field name* depends on the identifier type. For most types — `bban`, `iban`, `msisdn`, `bankgiro`, and `plusgiro` — only one field is mandatory. However, `gbDomestic` requires both `accountNumber` and `sortCode`.
3. The `bankAccount` cases, when supported by the source bank, that cannot be mapped to an `accountIdentifier` type and are therefore excluded from the source validation check comprise `CUSTOM`, `BANK`, `GUEST`, `SWIFT`, `ACH`, `TOKEN_AUTHORIZATION`, and `SECRET`.


### Bank-dependent field formatting

The bank's response may include a `fieldsFormatInformation` object array describing specific formatting constraints imposed by the bank. This typically involves which special characters are allowed, if any, and/or other formats, such as all caps, allowable numerals, etc.

The response syntax for `fieldsFormatInformation` will look something like this, in which `name` identifies the field and `path` is its location (in relation to `object.field`) within the `requestPayload`:


```json
"fieldsFormatInformation": [{ // bank-dependent formats indicating allowable characters
    "constraint": "^[A-Za-z0-9?:()./,\u0027+\\-\\s]*$"// regex indicating allowable characters
    "name": "description", // name of the field
    "path": "description", // field location in token request payload
}],
```

In the example above, the `constraint` field limits what can be included in the field specified by `name`; in this case, `description` in the token `requestPayload` for the given bank, which allows **A** through **Z**, **a** through **z**, **0** through **9**, question mark, colon, open parenthesis, close parenthesis, period, forward slash, comma, single quotation mark, plus sign, minus sign, and a space. All other characters or character codes are disallowed and, if included in the `description` field of a request submitted to this particular bank, an exception will be thrown.

See [https://regexr.com/3cr6f](https://regexr.com/3cr6f) to conveniently translate specific expressions, when necessary.

### Authentication: how do I identify the correct model?

Banks support different authentication models:

- **[Redirect](./sip/sip-v1/sip-v1-api-redirect)**– the user connects with the TPP but is redirected to the bank's web interface for authentication.
- **[Embedded](./sip/sip-v1/sip-v1-api-embedded)** – the payment process is executed entirely through the UI presented by the TPP.
- **[Decoupled](./sip/sip-v1/sip-v1-api-decoupled)** – the user authenticates using an external form of identification, for example, the bank's dedicated mobile app.


See [Authentication](../../integration-considerations/authentication-models) for a more detailed description of the authentication models.

Use the [GET /banks](../../api/reference/Banks-v1#operation/GatewayService.GetBanks) call to determine which authentication model is required. If the bank supports embedded and decoupled authentication, additional credentials will be available in the `credentialFields` field.

### Maintenance of bank information

We recommend that you maintain bank information regularly, by caching daily at 11pm UTC.

Use the [GET /banks](../../api/reference/Banks-v1#operation/GatewayService.GetBanks) call to retrieve bank information.

If you have any feedback about the developer documentation, please contact [devdocs@token.io](mailto:devdocs@token.io)