> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Account check

> Confirm a bank account belongs to the verified person from the account details they type, with no bank sign-in. IBAN, sort code, CLABE, CBU, IFSC and more.

The account check confirms that a bank account belongs to the person your workflow already verified, from the account details they type. There is no bank sign-in and no consent screen: the person enters their account the way their country writes it, and the bank confirms the name on it against the name an earlier step verified.

It is one of the two [Bank Verification methods](https://docs.didit.me/core-technology/bank-verification/verification-methods.md), next to bank sign-in, and its method value is `account_lookup`. Micro-deposits and the statement upload stay fallbacks after both. To check an account from your backend with no session, for example before a payout, use the [Account check API](https://docs.didit.me/standalone-apis/bank-account-check.md).

> [!NOTE]
>
> Bank Verification confirms who owns an account against an identity **another step** established, so it is not identity proof on its own. Put ID Verification, Database Validation, a questionnaire or `expected_details` before the step. The person never types a name for the check: Didit always compares the name the session already verified.

## How it works

**1. The person picks their country**

In the Bank Verification step, the person picks a country the step offers. Where the account check comes first there, the step opens a short form in that country's account format. Where bank sign-in comes first, the person picks **Enter your account details** to reach the form.

**2. The person types their account**

For example an IBAN, a sort code and an account number, or a CLABE. The verification flow builds the form from what the API returns for that country, so a country Didit adds later needs no change on your side.

**3. Didit checks the format first**

Before anything is billed, Didit checks each value: its length, its characters, its check digits and, for an IBAN, that it belongs to the selected country. A value that fails is refused with the field to fix. The person corrects it in place, and no attempt is spent.

**4. The bank checks the name on the account**

Didit runs one check against the name the session verified. Whatever else the client sends is ignored.

**5. The step decides**

The answer becomes an ownership result, and the step's actions turn it into the verdict exactly as they do for bank sign-in.

## Where the check is offered

Coverage is per country. Didit turns the check on country by country, once it has a priced route there; a country without one does not offer it. Countries are added over time, and the step always reads the current list, so you never need to change your integration when one is added.

Within a covered country, the step's methods decide whether the person sees it:

* **The step order.** `bank_method_order` sets which methods every country offers and which comes first. The default, `["open_banking", "account_lookup"]`, starts on bank sign-in and offers the account check as its backup.
* **A country's own order.** `methods` on a country in `bank_countries` overrides the step order there, for example `["account_lookup"]` for the account check only, or `["account_lookup", "open_banking"]` to start on it.
* **A bank that is down.** Where a country offers the account check, it also backs up a bank that bank sign-in has degraded or down: the step moves to the account form before any consent is asked, while the person has account checks left.
* **The check runs on Didit's own routes.** A step that runs on your own marketplace provider (`provider_key`) offers it only with `fallback_to_native` on.
* **Business accounts.** In a business verification session, the check compares a business account with the verified business, in the countries where Didit checks business accounts.

See [Choose the methods per country](https://docs.didit.me/core-technology/bank-verification/verification-methods.md#choose-the-methods-per-country) for the rules a save follows.

## What the person types

These are the account formats the form understands. They are not a coverage list: whether the check runs in a country depends on [where it is offered](#where-the-check-is-offered), and the step always shows the exact fields for that country.

| Account format | Countries | What the person types |
| - | - | - |
| IBAN | Countries that use IBANs | The full IBAN, which must belong to the selected country |
| Sort code and account number | United Kingdom | A 6-digit sort code and an 8-digit account number |
| Routing number and account number | United States | A 9-digit ABA routing number and the account number |
| Transit and institution number | Canada | The 8-digit transit and institution number (the 5-digit transit followed by the 3-digit institution) and the account number |
| BSB and account number | Australia | A 6-digit BSB and the account number |
| CLABE | Mexico | The 18-digit CLABE, which already names the bank |
| CBU or CVU | Argentina | The 22-digit CBU or CVU, which already names the bank |
| IFSC and account number | India | The 11-character IFSC and the account number |
| NUBAN and bank code | Nigeria | The 10-digit NUBAN and the bank's code or BIC |
| Account number | Other countries | The account number, and a bank code or BIC where the country needs one |

In some countries the form also asks for a registration number: for business accounts, and in a few countries for every account.

Spaces, dashes and dots are removed and letters are upper-cased before a value is checked, so the person can type an account the way their bank prints it.

## Turn it on

A new step offers the account check by default, as the backup to bank sign-in. To start on it, or to offer it alone, put `account_lookup` first in the order:

```json theme={null}
{
  "bank_method_order": ["account_lookup", "open_banking"]
}
```

These settings shape the check:

| Setting | Effect on the account check |
| - | - |
| `bank_method_order`, `bank_countries.<ISO3>.methods` | Whether a country offers the check, and whether it comes before or after bank sign-in. |
| `bank_countries` | The check runs only in the countries the step offers. |
| `bank_reference_identity` | The step whose verified name the account is checked against. |
| `bank_account_check_max_attempts` | How many checks the person gets, `1` to `5` (`3` by default). A separate count from bank sign-in's `bank_max_attempts`. |
| `bank_account_check_accept_close_match` | On (default): a close match goes to the close match confirmation, or to `bank_partial_match_action`. Off: every close match is a no match. |
| `bank_name_match_threshold`, `bank_partial_match_floor` | The same name score bands as bank sign-in: a match at or above the threshold (85 by default), and a close match, the partial match band, between the floor (70 by default) and the threshold. |
| `bank_use_provider_score` | On (default): the check's own name score decides when it is higher than Didit's, or when the check returns a score but no holder name, and `ownership.method` then reads `provider_only`. Off: an answer with no holder name is `not_verifiable`. |
| `bank_suggest_holder_name` | On (default): on a close match that names the holder, the person sees the name and confirms it is theirs or tries another account. |

## Results

### Checks that return an answer

Each of these is billed once and spends one of the person's account checks (`bank_account_check_max_attempts`). Until the step completes, the person can try again with another account while checks remain. The result is in `ownership.result`, except for an account that does not exist, which is in `connection.reason_code`.

| The check returns | Result | What decides |
| - | - | - |
| The account belongs to the verified person | `match` | The step approves, unless another of its checks says otherwise. |
| A close match that names the holder | `partial_match` | With `bank_suggest_holder_name` on, the person confirms the name or tries another account. Confirming ends the step on `bank_partial_match_action` (`REVIEW` by default). |
| A close match with a score but no holder name | `partial_match` | `bank_partial_match_action` (`REVIEW` by default). `ownership.method` reads `provider_only`. This needs `bank_use_provider_score` on, the default; with it off, the answer is `not_verifiable`. |
| The account belongs to someone else | `no_match` | `bank_no_match_action` (`DECLINE` by default). |
| An answer that compared no name | `not_verifiable` | `bank_not_verifiable_action` (`REVIEW` by default). |
| No account exists with these details | `ACCOUNT_NOT_FOUND` | The person can try another account while checks remain. |

With `bank_account_check_accept_close_match` off, both close matches are a `no_match` instead, with the reason code `OWNER_NAME_MISMATCH`: the person is never asked to confirm the name, and `bank_no_match_action` decides. Bank sign-in keeps its close matches either way.

Once the person has spent every account check, and every bank sign-in attempt where the country also offers bank sign-in, without a successful connection, the step ends on `bank_attempts_exhausted_action` (`DECLINE` by default).

### Outcomes that are never billed

None of these spends a check. Each is shown in `connection.reason_code`.

| What happens | Reason code | What follows |
| - | - | - |
| The account is refused as typed, by Didit's format check or by the bank | `INVALID_ACCOUNT_INPUT`, while the attempt stays open | The person is told which field to fix and corrects it. |
| The check is unavailable right now | `PROVIDER_UNAVAILABLE` | The person can try again. |
| The session has no verified name to compare | `REFERENCE_IDENTITY_MISSING` | The check never runs. The step ends on `bank_reference_identity_missing_action` (`REVIEW` by default). |

### In the decision

The session decision lists the step under `bank_verifications[]`. Once an account has been evaluated, `method` reads `account_lookup`. While no account has been evaluated, `method` and `ownership` are `null`, and `connection.reason_code` says why, for example `ACCOUNT_NOT_FOUND`, `PROVIDER_UNAVAILABLE` or `REFERENCE_IDENTITY_MISSING`.

No bank is picked for the check, so `connection.institution_id`, `connection.institution_name` and `connection.oauth` are `null`, and `connection.institution_country` is the country the person picked. Didit keeps no access to the account once the step completes, so a check that ended on a match reads `connection.status: revoked` with `reason_code: VERIFICATION_COMPLETED`. The result itself stays on the session.

An account check reads no balances, transactions or income. When the step asks for them, `financial_data.not_collected` lists them; see [Financial data needs bank sign-in](https://docs.didit.me/core-technology/bank-verification/verification-methods.md#financial-data-needs-bank-sign-in).

```json theme={null}
{
  "bank_verifications": [
    {
      "status": "Approved",
      "method": "account_lookup",
      "connection": {
        "status": "revoked",
        "institution_id": null,
        "institution_name": null,
        "institution_country": "ESP",
        "oauth": null,
        "attempts": 1,
        "reason_code": "VERIFICATION_COMPLETED"
      },
      "ownership": {
        "result": "match",
        "method": "exact"
      },
      "financial_data": {
        "balances": null,
        "transactions": null,
        "income": null,
        "categorization": null,
        "not_collected": []
      },
      "billing": {
        "route": "native",
        "billed": true,
        "marketplace_fee": null,
        "usage_type": "bank_verification"
      }
    }
  ]
}
```

The example shows only the fields this page discusses. Once an account has been evaluated, read `method` to tell an account check apart from bank sign-in: it is the one field meant for that.

### In workflow rules and reports

* **Branches and status rules:** `bank.method` is `account_lookup` (**Account Check** in the rule builder), and `bank.reason_code` can be `ACCOUNT_NOT_FOUND`.
* **Session PDF report:** the **Verification method** row reads **Account check**.

## Pricing

Each check that returns an answer is one Bank Verification charge: a match, a close match, a no match, an account it could not verify and an account it did not find are all billed. A value refused before the check, a check that is unavailable and a session with no verified name to compare are never billed. The price is set per country.

The account check is a paid method of its own, never a fallback: `bank_fallback_used_action` does not fire for it. After a billed check, micro-deposits and the statement upload are included at no extra charge in the same session, where the step turns them on and the country offers them.

## Test it in sandbox

In a sandbox application, the check runs on a simulated service and nothing is billed. Sandbox offers both methods in every country, in the order the step sets: with the default order, pick **Enter your account details** to run the check, or set `bank_method_order` to `["account_lookup", "open_banking"]` to start on it.

The last four characters of the account the person types (the IBAN, else the account number) choose the answer. Any other ending matches the verified name.

| Ends in | Answer |
| - | - |
| `0001` | A close match that names the holder: the person is asked to confirm the name. With `bank_account_check_accept_close_match` off, a no match. |
| `0002` | A close match with no holder name: `bank_partial_match_action` decides. With `bank_use_provider_score` off, the answer is `not_verifiable`; with `bank_account_check_accept_close_match` off, a no match. |
| `0003` | No match: the account belongs to someone else. Spends a check. |
| `0004` | Answered but compared no name (`not_verifiable`). Spends a check. |
| `0005` | The check is unavailable (`PROVIDER_UNAVAILABLE`). Free to retry. |
| `0006` | No account with these details (`ACCOUNT_NOT_FOUND`). Spends a check. |
| `0009` | Refused as typed: the person is asked to correct the field. The attempt stays open. |

Sandbox records each answered check as usage at no cost, so you can see which checks a live session would bill.

An IBAN, a CLABE and a CBU carry check digits, so you cannot simply change their last four characters. Use these values, which pass every format check:

**Germany (IBAN)**

| Answer | IBAN |
| - | - |
| Match | `DE43123456789012345678` |
| `0001` | `DE62123456789012340001` |
| `0002` | `DE35123456789012340002` |
| `0003` | `DE08123456789012340003` |
| `0004` | `DE78123456789012340004` |
| `0005` | `DE51123456789012340005` |
| `0006` | `DE24123456789012340006` |
| `0009` | `DE40123456789012340009` |

**United Kingdom**

Sort code `123456`, with:

| Answer | Account number |
| - | - |
| Match | `12345678` |
| `0001` | `12340001` |
| `0002` | `12340002` |
| `0003` | `12340003` |
| `0004` | `12340004` |
| `0005` | `12340005` |
| `0006` | `12340006` |
| `0009` | `12340009` |

**United States**

Routing number `021000021`, with:

| Answer | Account number |
| - | - |
| Match | `000123456789` |
| `0001` | `000123450001` |
| `0002` | `000123450002` |
| `0003` | `000123450003` |
| `0004` | `000123450004` |
| `0005` | `000123450005` |
| `0006` | `000123450006` |
| `0009` | `000123450009` |

**Mexico (CLABE)**

| Answer | CLABE |
| - | - |
| Match | `002010077777777771` |
| `0001` | `002010077777780001` |
| `0002` | `002010077777750002` |
| `0003` | `002010077777720003` |
| `0004` | `002010077777790004` |
| `0005` | `002010077777760005` |
| `0006` | `002010077777730006` |
| `0009` | `002010077777740009` |

**Argentina (CBU)**

| Answer | CBU |
| - | - |
| Match | `2850590940090418135201` |
| `0001` | `2850590940090418160001` |
| `0002` | `2850590940090418170002` |
| `0003` | `2850590940090418180003` |
| `0004` | `2850590940090418190004` |
| `0005` | `2850590940090418100005` |
| `0006` | `2850590940090418110006` |
| `0009` | `2850590940090418140009` |

**India**

IFSC `ALLA0211480`, with:

| Answer | Account number |
| - | - |
| Match | `123456789007` |
| `0001` | `123456780001` |
| `0002` | `123456780002` |
| `0003` | `123456780003` |
| `0004` | `123456780004` |
| `0005` | `123456780005` |
| `0006` | `123456780006` |
| `0009` | `123456780009` |

The [Account check API](https://docs.didit.me/standalone-apis/bank-account-check.md) answers a sandbox key from the same endings, with no session.

See [Sandbox testing](https://docs.didit.me/integration/sandbox-testing.md) for how sandbox applications work in general.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.