> ## 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 API

> Check that a bank account belongs to the person or company you name, before you send money to it. No session and no sign-in.

Your backend sends the name and the account, and reads the result. It is the [account check](https://docs.didit.me/core-technology/bank-verification/account-check.md) of the Bank Verification step, without the person.

## Send the account the way its country writes it

| Country | `account` |
| - | - |
| IBAN countries | `{"iban": "..."}` |
| United Kingdom | `{"sort_code": "...", "account_number": "..."}` |
| United States | `{"routing_number": "...", "account_number": "..."}` |
| Canada | `{"transit_institution": "...", "account_number": "..."}` |
| Australia | `{"bsb": "...", "account_number": "..."}` |
| India | `{"ifsc": "...", "account_number": "..."}` |
| Nigeria | `{"bank_code": "...", "account_number": "..."}` |
| Mexico | `{"clabe": "..."}` |
| Argentina | `{"cbu_cvu": "..."}` |

Some countries also ask for a `bic`, and for a business account a `registration_id`. Spaces, dashes and dots are ignored. A key the country's check needs and does not get is a `400` naming it, for example `"field": "account.sort_code", "reason": "required"`.

Send `holder.full_name` to check a person's account, or `holder.business_name` to check a company's.

## Read the result

| `result` | What it means | Typical next step |
| - | - | - |
| `match` | The bank holds the account under the name you sent. | Send the money. |
| `close_match` | The bank holds it under a close name. `holder_name` is that name, when the bank returned it. | Compare `holder_name`, or ask the person to confirm. |
| `no_match` | The bank holds it under another name, or there is no such account. | Do not send the money. |
| `cannot_verify` | The bank answered without comparing the name, for example for a blocked or closed account. | Apply your own policy, for example ask for another account. |

## Billing and retries

Each check the bank answers is billed once at the Account check price of the account's country, whatever the result. A request answered with an error is never billed: a refused body (`400`), no credit (`402`), an account no check serves yet (`404`) or a bank that could not answer (`503`).

There is no idempotency key and no endpoint to read a check back. A retried request runs a new check, with a new `request_id`, and is billed again, so store the response. Didit stores only the charge, with the request ID, the country, the result and the masked account, never the name or the full account number.

## Test it in sandbox

A sandbox API key calls no bank and is charged nothing. The last 4 characters of the IBAN, else of the account number, choose the answer:

| Ends in | Answer |
| - | - |
| `0001` | `close_match`, with a `holder_name` |
| `0002` | `close_match`, `holder_name: null` |
| `0003`, `0006` | `no_match` |
| `0004` | `cannot_verify` |
| `0005` | `503`, `account_check_unavailable` |
| `0009` | `400`, `reason: rejected` |
| Anything else | `match` |

An IBAN, a CLABE and a CBU carry check digits: use the [sandbox values](https://docs.didit.me/core-technology/bank-verification/account-check.md#test-it-in-sandbox) that pass every format check.

## Access

Authenticate with your application's `x-api-key`, or with its client-credentials bearer token. A scoped API key needs write access to sessions. The endpoint shares the write limit of 300 requests per minute per API key.


## OpenAPI

````yaml POST /v3/bank/account-check/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: Identity verification API. Authenticate with x-api-key header.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/bank/account-check/:
    post:
      tags:
        - Standalone APIs
      summary: Check a bank account
      description: >-
        Check that a bank account belongs to the person or company you name,
        before you send money to it. No session and no sign-in: send the name
        and the account, read the result. It is the [account
        check](/core-technology/bank-verification/account-check) of the Bank
        Verification step, run from your backend.


        **What you send.** The account's `country` (ISO 3166-1 alpha-3), the
        `account` the way that country writes it, and the `holder` name:
        `full_name` for a person or `business_name` for a company. A business
        name checks a business account.


        **What you get back.** `result` is `match`, `close_match`, `no_match` or
        `cannot_verify`. On a `close_match`, `holder_name` is the name the bank
        holds the account under, when the bank returned it. `account` comes back
        masked to its last 4 characters.


        **Billing.** Each check the bank answers is billed once at the Account
        check price of the account's country, whatever the result: a `no_match`,
        an account that does not exist and a `cannot_verify` are billed too. A
        request answered with an error is never billed.


        **Every request is a new check.** There is no idempotency key and no
        endpoint to read a check back, so a retried request runs, and is billed,
        again. Store the response.


        **Sandbox.** A sandbox key calls no bank and is charged nothing. The
        last 4 characters of the IBAN, else of the account number, choose the
        answer: `0001` a `close_match` with a `holder_name`, `0002` a
        `close_match` without one, `0003` and `0006` a `no_match`, `0004`
        `cannot_verify`, `0005` a `503` and `0009` a `400`. Any other ending is
        a `match`.


        **API keys.** A scoped API key needs write access to sessions.
      operationId: post_v3_bank_account_check
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BankAccountCheckRequest'
            examples:
              Person, United Kingdom:
                summary: >-
                  A sort code and account number, checked against a person's
                  name
                value:
                  country: GBR
                  account:
                    sort_code: 20-45-67
                    account_number: '31926819'
                  holder:
                    full_name: Maria Oliveira
                  vendor_data: payout_20481
              Company, IBAN:
                summary: An IBAN, checked against a company's name
                value:
                  country: DEU
                  account:
                    iban: DE89 3704 0044 0532 0130 00
                  holder:
                    business_name: Northwind Trading GmbH
      responses:
        '200':
          description: The bank answered. The check is billed, whatever the result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankAccountCheckResponse'
              examples:
                Close match:
                  summary: The bank holds the account under a close name
                  value:
                    request_id: c2f4a9e0-7b1d-4c3a-9e55-1d0a6b8f2a47
                    result: close_match
                    holder_name: MARIA R OLIVEIRA
                    account: '****6819'
                    vendor_data: payout_20481
                    created_at: '2026-10-21T14:32:08Z'
                Match:
                  summary: The bank holds the account under the name sent
                  value:
                    request_id: 5b0e2d7c-41a8-4f6e-9c3b-8e7d1a2f6c90
                    result: match
                    holder_name: null
                    account: '****3000'
                    vendor_data: null
                    created_at: '2026-10-21T14:35:41Z'
        '400':
          description: >-
            Refused as sent, and not billed. `field` names the body field to
            correct and `reason` says why, with the same reasons the hosted
            account form shows. Only the first refused field is reported.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankAccountCheckError'
              examples:
                Missing field:
                  summary: The country's check needs a sort code
                  value:
                    detail: The sort code is not valid (required).
                    code: invalid_account_input
                    field: account.sort_code
                    reason: required
                Invalid IBAN:
                  summary: The IBAN has the wrong length for its country
                  value:
                    detail: The iban is not valid (length).
                    code: invalid_account_input
                    field: account.iban
                    reason: length
                Refused by the bank:
                  summary: The bank refused the account as sent
                  value:
                    detail: The account was refused as typed (rejected).
                    code: invalid_account_input
                    field: account.account_number
                    reason: rejected
                No name:
                  summary: '`holder` has neither `full_name` nor `business_name`'
                  value:
                    detail: >-
                      Send full_name for a person or business_name for a
                      company.
                    code: invalid_account_input
                    field: holder
                    reason: required
        '401':
          description: The scoped API key has expired.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankAccountCheckError'
              examples:
                Expired key:
                  summary: The key's expiry date has passed
                  value:
                    detail: This API key has expired.
        '402':
          description: >-
            The check cannot be paid for, so it did not run. Top up your
            balance, then send it again.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankAccountCheckError'
              examples:
                Out of credit:
                  summary: Your balance cannot cover one check
                  value:
                    detail: >-
                      You don't have enough credits to perform this request.
                      Please top up at https://business.didit.me
                    code: insufficient_credits
                Not in your contract:
                  summary: Your contract has no price for the Account check API
                  value:
                    detail: >-
                      Your contract does not price the Account check API.
                      Contact your account manager.
                    code: contract_rate_missing
        '403':
          description: >-
            The `x-api-key` header or the bearer token is missing or invalid,
            the request came from an address outside the key's IP list, or a
            scoped key has no write access to sessions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankAccountCheckError'
              examples:
                Missing or invalid credentials:
                  summary: No valid API key or token
                  value:
                    detail: You do not have permission to perform this action.
                No sessions write:
                  summary: A scoped key without write access to sessions
                  value:
                    detail: This API key has no write access to sessions.
        '404':
          description: >-
            No account check serves this account yet, so nothing was checked or
            billed. `country_not_covered`: none serves its country, or its kind
            of account (person or business) there. `bank_not_covered`: none
            serves its bank. `bank_verification_not_available`: Bank
            Verification is not available yet.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankAccountCheckError'
              examples:
                Country not covered:
                  summary: No account check serves the country
                  value:
                    detail: No account check serves this country yet.
                    code: country_not_covered
                Bank not covered:
                  summary: No account check serves the account's bank
                  value:
                    detail: No account check serves this account's bank yet.
                    code: bank_not_covered
        '429':
          $ref: '#/components/responses/RateLimitedWrite'
        '503':
          description: >-
            The bank could not answer. Nothing was checked or billed; send the
            check again later.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankAccountCheckError'
              examples:
                Unavailable:
                  summary: The bank did not answer
                  value:
                    detail: >-
                      The account check is temporarily unavailable and this
                      request was not charged. Please try again.
                    code: account_check_unavailable
      security:
        - ApiKeyAuth: []
        - BearerAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl -X POST https://verification.didit.me/v3/bank/account-check/ \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "country": "GBR",
                "account": {"sort_code": "20-45-67", "account_number": "31926819"},
                "holder": {"full_name": "Maria Oliveira"},
                "vendor_data": "payout_20481"
              }'
        - lang: python
          label: Python
          source: |-
            import os, requests

            resp = requests.post(
                "https://verification.didit.me/v3/bank/account-check/",
                headers={"x-api-key": os.environ["DIDIT_API_KEY"]},
                json={
                    "country": "GBR",
                    "account": {"sort_code": "20-45-67", "account_number": "31926819"},
                    "holder": {"full_name": "Maria Oliveira"},
                    "vendor_data": "payout_20481",
                },
                timeout=30,
            )
            resp.raise_for_status()
            check = resp.json()
            if check["result"] == "match":
                pass  # send the payout
            elif check["result"] == "close_match":
                print(check["holder_name"])  # the name the bank holds, when it returned one
        - lang: javascript
          label: JavaScript
          source: >-
            const res = await
            fetch('https://verification.didit.me/v3/bank/account-check/', {
              method: 'POST',
              headers: {
                'x-api-key': process.env.DIDIT_API_KEY,
                'Content-Type': 'application/json',
              },
              body: JSON.stringify({
                country: 'GBR',
                account: { sort_code: '20-45-67', account_number: '31926819' },
                holder: { full_name: 'Maria Oliveira' },
                vendor_data: 'payout_20481',
              }),
            });

            const check = await res.json();

            // check.result: match, close_match, no_match or cannot_verify
components:
  schemas:
    BankAccountCheckRequest:
      type: object
      required:
        - country
        - account
        - holder
      properties:
        country:
          type: string
          minLength: 3
          maxLength: 3
          description: >-
            The account's country, as an ISO 3166-1 alpha-3 code, for example
            `GBR`. Lowercase is accepted.
          example: GBR
        account:
          type: object
          description: >-
            The account the way its country writes it: an `iban`, or an
            `account_number` with the bank or branch code the country needs
            (`sort_code`, `routing_number`, `transit_institution`, `bsb`,
            `ifsc`, `bank_code` or `bic`). Mexico takes a `clabe` and Argentina
            a `cbu_cvu`, which already name the bank. A business account adds a
            `registration_id` where the country asks for one. Spaces, dashes and
            dots are ignored. Keys the country's check does not use are ignored;
            a key it needs and does not get is a `400` that names it.
          properties:
            iban:
              type: string
              maxLength: 64
              description: >-
                The IBAN, in a country that uses IBANs. It must belong to
                `country`.
            account_number:
              type: string
              maxLength: 64
              description: >-
                The account number, in a country that writes the account with a
                separate bank or branch code.
            sort_code:
              type: string
              maxLength: 64
              description: 'United Kingdom: the 6-digit sort code.'
            routing_number:
              type: string
              maxLength: 64
              description: 'United States: the 9-digit ABA routing number.'
            transit_institution:
              type: string
              maxLength: 64
              description: 'Canada: the 8-digit transit and institution number.'
            bsb:
              type: string
              maxLength: 64
              description: 'Australia: the 6-digit BSB.'
            ifsc:
              type: string
              maxLength: 64
              description: 'India: the 11-character IFSC.'
            bank_code:
              type: string
              maxLength: 64
              description: >-
                The bank's code, where the country needs one, for example in
                Nigeria.
            bic:
              type: string
              maxLength: 64
              description: The bank's BIC, where the country's check asks for one.
            clabe:
              type: string
              maxLength: 64
              description: 'Mexico: the 18-digit CLABE. It already names the bank.'
            cbu_cvu:
              type: string
              maxLength: 64
              description: 'Argentina: the 22-digit CBU or CVU. It already names the bank.'
            registration_id:
              type: string
              maxLength: 64
              description: >-
                A business account's registration number, where the country asks
                for one.
          additionalProperties:
            type: string
            maxLength: 64
          example:
            sort_code: 20-45-67
            account_number: '31926819'
        holder:
          $ref: '#/components/schemas/BankAccountCheckHolder'
        vendor_data:
          type: string
          nullable: true
          description: Your own reference for this check, returned unchanged.
          example: payout_20481
    BankAccountCheckResponse:
      type: object
      required:
        - request_id
        - result
        - holder_name
        - account
        - vendor_data
        - created_at
      properties:
        request_id:
          type: string
          format: uuid
          description: The ID of this check.
        result:
          type: string
          enum:
            - match
            - close_match
            - no_match
            - cannot_verify
          description: >-
            `match`: the bank holds the account under the name you sent.
            `close_match`: under a close name, for example a missing middle name
            or a typo. `no_match`: under another name, or there is no such
            account. `cannot_verify`: the bank answered without comparing the
            name, for example for a blocked or closed account.
        holder_name:
          type: string
          nullable: true
          description: >-
            Only on a `close_match`, and only when the bank returned it: the
            name on the account, as the bank holds it. `null` otherwise.
        account:
          type: string
          description: The account, masked to its last 4 characters.
        vendor_data:
          type: string
          nullable: true
          description: Your own reference, as you sent it.
        created_at:
          type: string
          format: date-time
          description: When the check ran, in UTC.
    BankAccountCheckError:
      type: object
      required:
        - detail
      properties:
        detail:
          type: string
          description: What went wrong, in English.
        code:
          type: string
          description: A stable code to branch on. Absent on `401` and `403`.
        field:
          type: string
          description: >-
            `400` only: the body field to correct, as a dotted path, for example
            `account.sort_code`.
        reason:
          type: string
          enum:
            - required
            - length
            - format
            - checksum
            - country_mismatch
            - rejected
          description: >-
            `400` only: why the field was refused. `required`, `length`,
            `format`, `checksum` and `country_mismatch` (an IBAN of another
            country) are Didit's own checks; `rejected` means the bank refused
            the account as sent.
    BankAccountCheckHolder:
      description: >-
        The name the account is checked against. Send exactly one of `full_name`
        and `business_name`.
      oneOf:
        - $ref: '#/components/schemas/BankAccountCheckPersonHolder'
        - $ref: '#/components/schemas/BankAccountCheckBusinessHolder'
    BankAccountCheckPersonHolder:
      type: object
      description: The person who should hold the account.
      required:
        - full_name
      properties:
        full_name:
          type: string
          maxLength: 255
          description: The full name of the person who should hold the account.
          example: Maria Oliveira
    BankAccountCheckBusinessHolder:
      type: object
      description: The company that should hold the account. Checks a business account.
      required:
        - business_name
      properties:
        business_name:
          type: string
          maxLength: 255
          description: >-
            The name of the company that should hold the account. Checks a
            business account.
  responses:
    RateLimitedWrite:
      description: >-
        The shared write limit of 300 requests per minute per API key was
        exceeded. Honor `Retry-After` before retrying.
      content:
        application/json:
          schema:
            type: object
            required:
              - detail
            properties:
              detail:
                type: string
          example:
            detail: >-
              Write request rate limit exceeded. You can make up to 300 requests
              per minute.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Your application's API key, from Developers -> API keys in the Business
        Console. The primary key has full access. A named key can be scoped:
        none, read or write per resource, limited to some workflows or to
        approved sessions, to a list of IP addresses, and to an expiry date. 401
        means the key is missing, wrong, revoked or expired; 403 means the key
        has no access to this resource or action, or the request came from an
        address outside its IP list; 404 on a session route means the session is
        outside the key's workflows or statuses. A key without media access
        receives image, video and PDF URLs as null, and a key without sessions
        write receives session links and tokens as null. See
        https://docs.didit.me/console/api-keys.
    BearerAuth:
      type: http
      scheme: bearer
      description: The application's client-credentials access token.

````

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