Skip to content

Bank Accounts ​

For the end-to-end flow, see Bank account verification.

Bank accounts can be associated with a case and used to run Bank Account Verification (BAV) checks. Each bank account stores the account holder's name, country, country-specific account identifiers, and optionally the bank name. The identifiers can be corrected until BAV has been run or requested for the account. The holder name, country, format, and bank name can't be changed: to correct those, delete the account and create a new one.

Supported countries and the fields each one requires are listed under supported countries. UK accounts can still be submitted with sortCode and accountNumber. Other countries use bankFields with the field keys from those formats (for example iban, bsb, or us_routing_number).

Bank accounts can be created explicitly via the API below, or automatically when a bank statement is uploaded and extracted. In both cases, when BAV is enabled, a Bank account verification check is enqueued for the new account.


Supported countries ​

The table below is a snapshot of the active formats the API accepts. List bank account formats is the live source of truth for field keys, lengths, and validation rules — this list can lag a database change.

Submit identifiers in bankFields using the required and optional field keys. UK accounts can omit bankFields and send sortCode and accountNumber instead.

CountryCodeformatCodeRequiredOptionalNotes
ArgentinaARAR_ARS_LOCAL_CBUcbu22 digits
AustraliaAUAU_AUD_LOCALbsb, account_numberbsb 6 digits; account_number 5–9 digits
AustriaATAT_EUR_SEPAibanIBAN 20 characters
BangladeshBDBD_BBAN_SWIFTbd_bban, bicbd_bban is routing number plus account
BelgiumBEBE_EUR_SEPAibanbicIBAN 16 characters
BrazilBRBR_IBANibanbicIBAN 29 characters
CroatiaHRHR_EUR_SEPAibanIBAN 21 characters
CyprusCYCY_EUR_SEPAibanIBAN 28 characters
EstoniaEEEE_EUR_SEPAibanIBAN 20 characters
FinlandFIFI_EUR_SEPAibanIBAN 18 characters
FranceFRFR_EUR_SEPAibanbicIBAN 27 characters
GermanyDEDE_EUR_SEPAibanIBAN 22 characters
GreeceGRGR_EUR_SEPAibanIBAN 27 characters
IndiaININ_INR_LOCALifsc, account_numberifsc 11 characters; account_number 1–35
IndonesiaIDID_IDR_SWIFTid_bban, bicid_bban 1–22 digits
IrelandIEIE_EUR_SEPAibanIBAN 22 characters
ItalyITIT_EUR_SEPAibanbicIBAN 27 characters
LatviaLVLV_EUR_SEPAibanIBAN 21 characters
LuxembourgLULU_EUR_SEPAibanIBAN 20 characters
MalaysiaMYMY_MYR_SWIFTmy_bban, bicmy_bban 5–19 digits
MaltaMTMT_EUR_SEPAibanIBAN 31 characters
MexicoMXMX_MXN_LOCALclabe18 digits
NepalNPNP_NPR_SWIFTnp_bban, bic
NetherlandsNLNL_EUR_SEPAibanbicIBAN 18 characters
NigeriaNGNG_NGN_SWIFTng_bban, bicng_bban 10 digits
PakistanPKPK_IBANibanbicIBAN 24 characters
PeruPEPE_PEN_LOCALcci20 digits
PolandPLPL_EUR_SEPAibanbicIBAN 28 characters
PortugalPTPT_EUR_SEPAibanIBAN 25 characters
SlovakiaSKSK_EUR_SEPAibanIBAN 24 characters
SloveniaSISI_EUR_SEPAibanIBAN 19 characters
South AfricaZAZA_ZAR_LOCALza_branch_code, za_account_numberza_branch_code 6 digits; za_account_number 6–12 digits
South KoreaKRKR_KRW_LOCALkr_bank_code, kr_account_numberkr_bank_code 3 digits; kr_account_number 11–20 digits
SpainESES_EUR_SEPAibanIBAN 24 characters
ThailandTHTH_THB_SWIFTth_bban, bicth_bban 7–12 digits
UgandaUGUG_SWIFTug_bban, bic
United Arab EmiratesAEAE_AED_SWIFTibanIBAN 23 characters
United KingdomGBGB_GBP_LOCALsort_code, account_numbersort_code 6 digits; account_number 8 digits. UK accounts can also use sortCode and accountNumber
United StatesUSUS_USD_ACHus_routing_number, us_account_numberus_routing_number 9 digits; us_account_number 4–17 digits
UruguayUYUY_UYU_LOCALuy_bank_code, uy_account_numberuy_bank_code 3 digits; uy_account_number 4–14 digits

Optional bic is only configured on some IBAN and SEPA formats (Belgium, Brazil, France, Italy, Netherlands, Pakistan, Poland). Later SEPA and SWIFT IBAN formats are IBAN-only unless bic is listed as required.


List bank account formats ​

Returns the active bank account formats that can be submitted through the API. Use the returned fieldKey values in bankFields when creating a bank account.

GET /api/static/bank-account-formats
Query parameterRequiredNotes
countryCodeISO 3166-1 alpha-2 code, for example GB or FR
currencyCodeISO 4217 currency code, for example GBP or EUR
paymentRailFormat rail, for example LOCAL, SEPA, IBAN, SWIFT, or ACH

Response 200 OK

json
[
    {
        "id": 1,
        "countryCode": "GB",
        "currencyCode": "GBP",
        "paymentRail": "LOCAL",
        "formatCode": "GB_GBP_LOCAL",
        "displayName": "UK local bank account",
        "fields": [
            {
                "bankFieldTypeId": 4,
                "fieldKey": "sort_code",
                "displayName": "Sort code",
                "description": "UK bank routing code",
                "displayOrder": 1,
                "isRequired": true,
                "label": "Sort code",
                "minLength": 6,
                "maxLength": 6,
                "validationRegex": "^\\d{6}$",
                "validationMessage": "Must be 6 digits.",
                "displayFormat": "00-00-00",
                "normalizationRule": "digits_only"
            },
            {
                "bankFieldTypeId": 3,
                "fieldKey": "account_number",
                "displayName": "Account number",
                "displayOrder": 2,
                "isRequired": true,
                "label": "Account number",
                "minLength": 8,
                "maxLength": 8,
                "validationRegex": "^\\d{8}$",
                "validationMessage": "Must be 8 digits.",
                "normalizationRule": "digits_only"
            }
        ]
    },
    {
        "id": 6,
        "countryCode": "FR",
        "currencyCode": "EUR",
        "paymentRail": "SEPA",
        "formatCode": "FR_EUR_SEPA",
        "displayName": "French SEPA bank account",
        "fields": [
            {
                "fieldKey": "iban",
                "displayName": "IBAN",
                "displayOrder": 1,
                "isRequired": true,
                "label": "IBAN",
                "minLength": 27,
                "maxLength": 27,
                "validationRegex": "^FR\\d{12}[A-Z0-9]{11}\\d{2}$",
                "validationMessage": "Must be FR + 12 digits + 11 chars + 2 digits.",
                "normalizationRule": "uppercase_no_spaces"
            },
            {
                "fieldKey": "bic",
                "displayName": "BIC",
                "displayOrder": 2,
                "isRequired": false,
                "label": "BIC / SWIFT code",
                "minLength": 8,
                "maxLength": 11,
                "normalizationRule": "uppercase_no_spaces"
            }
        ]
    }
]

The returned formats are the source of truth for supported countries and field requirements. Do not hard-code field keys beyond UK sortCode / accountNumber aliases.


List bank accounts ​

Returns all active bank accounts associated with a case. Each bank account includes the latest completed BAV attempt and the full BAV history, both ordered by most recent first.

sortCode and accountNumber remain on the response for UK accounts. Country-specific identifiers are always returned in fields. formatCode is the format that was matched at create time. canEdit says whether the account's identifiers can still be updated.

GET /api/cases/{caseId}/bank-accounts

Response 200 OK

json
[
    {
        "id": 1,
        "caseId": 123,
        "documentId": null,
        "countryCode": "GB",
        "formatCode": "GB_GBP_LOCAL",
        "firstName": "MICHELLE",
        "middleNames": null,
        "lastName": "BOYNTON",
        "organisationName": null,
        "sortCode": "207106",
        "accountNumber": "12345678",
        "bankName": "Monzo",
        "latestBavAttempt": {
            "id": 99,
            "createTs": "2025-08-27T14:16:14Z",
            "bankName": "Monzo",
            "riskRating": {
                "id": 1,
                "name": "Low"
            }
        },
        "bavAttemptHistory": [
            {
                "id": 99,
                "createTs": "2025-08-27T14:16:14Z",
                "bankName": "Monzo",
                "riskRating": {
                    "id": 1,
                    "name": "Low"
                }
            }
        ],
        "fields": [
            {
                "fieldKey": "sort_code",
                "displayName": "Sort code",
                "displayOrder": 1,
                "value": "207106"
            },
            {
                "fieldKey": "account_number",
                "displayName": "Account number",
                "displayOrder": 2,
                "value": "12345678"
            }
        ],
        "canEdit": false
    },
    {
        "id": 2,
        "caseId": 123,
        "documentId": null,
        "countryCode": "FR",
        "formatCode": "FR_EUR_SEPA",
        "firstName": "MICHELLE",
        "middleNames": null,
        "lastName": "BOYNTON",
        "organisationName": null,
        "sortCode": null,
        "accountNumber": null,
        "bankName": "BNP Paribas",
        "latestBavAttempt": null,
        "bavAttemptHistory": [],
        "fields": [
            {
                "fieldKey": "iban",
                "displayName": "IBAN",
                "displayOrder": 1,
                "value": "FR1420041010050500013M02606"
            },
            {
                "fieldKey": "bic",
                "displayName": "BIC",
                "displayOrder": 2,
                "value": "BNPAFRPP"
            }
        ],
        "canEdit": true
    }
]

latestBavAttempt will be null if no completed BAV check has been run against this account yet. bavAttemptHistory will be an empty array in the same case. bankName may be null on both the bank account and individual BAV attempts if the bank name was not available from the source.


Create a bank account ​

Creates a new bank account against a case. countryCode must be a valid ISO 3166-1 alpha-2 code that has an active format in bank account formats.

Submit identifiers in bankFields using the format fieldKey values. When formatCode is omitted, create matches an active format for the country from the submitted bankFields. Provide formatCode to pin a specific format when more than one could apply.

Person cases send firstName and lastName. Entity cases send organisationName instead of person names. Bank account verification on an entity case does not use an address.

UK accounts can omit bankFields and send sortCode and accountNumber instead. Those properties are ignored when bankFields contains any values.

Values are normalised and validated against the selected format (required fields, length, and regex). Spaces and punctuation are stripped where the format defines a normalisation rule — for example a UK sort code of 20-71-06 is stored as 207106. IBANs can be sent in their printed form, with spaces and in either case: de89 3704 0044 0532 0130 00 is stored as DE89370400440532013000.

When creation succeeds and BAV is enabled, a Bank account verification check is enqueued automatically for the new account. The same happens when a bank account is created from an extracted bank statement. Returning an existing account does not enqueue another check.

POST /api/cases/{caseId}/bank-accounts

Request — UK

json
{
    "countryCode": "GB",
    "firstName": "MICHELLE",
    "middleNames": null,
    "lastName": "BOYNTON",
    "sortCode": "207106",
    "accountNumber": "12345678",
    "bankName": "Monzo"
}

Request — international

json
{
    "countryCode": "FR",
    "firstName": "MICHELLE",
    "lastName": "BOYNTON",
    "formatCode": "FR_EUR_SEPA",
    "bankName": "BNP Paribas",
    "bankFields": {
        "iban": "FR1420041010050500013M02606",
        "bic": "BNPAFRPP"
    }
}

Request — Entity (UK)

json
{
    "countryCode": "GB",
    "organisationName": "ACME LIMITED",
    "sortCode": "207106",
    "accountNumber": "12345678",
    "bankName": "Monzo"
}

Response 200 OK

Returns the ID of the bank account. If the case already has an account for the same country that has not been deleted, and the normalised identifiers match, that account's ID is returned and no new account is created. A match keeps the existing account's details. Matching applies to an IBAN, a sort code with an account number, or a BSB with an account number. Holder name, bank name, and BIC are ignored, so the same IBAN sent again with a different holder name or BIC still returns the existing account. Other formats, such as a US routing number and account number, a CLABE, or a BBAN, are not matched: sending them again creates another account, and a verification check can be enqueued for that new account. Deleting an account and creating it again makes a new one.

json
1

Response 400 Bad Request

Returned if the country is not recognised, no format is configured for the country, or the supplied fields fail validation.

json
[
    {
        "fieldKey": "iban",
        "message": "IBAN is required."
    }
]

Update a bank account ​

Replaces a bank account's identifiers, for example to correct an IBAN or sort code that failed validation. The account keeps its id, country, format, holder name, and bank name. To change any of those, delete the account and create a new one.

An account can only be updated while canEdit is true in List bank accounts. Once BAV has been run or requested for the account, its identifiers can't be changed. A BAV check that stopped because the account's details failed validation doesn't count, so those accounts can still be corrected.

The request replaces all of the account's identifiers, so send the full set each time. Required fields must be included, and an optional field you leave out (such as bic) is removed. Values are normalised and validated against the account's format, as on create. UK accounts can send sortCode and accountNumber instead of bankFields. Those properties are ignored when bankFields contains any values.

When the identifiers change and BAV is enabled, a Bank account verification check is enqueued for the account if it now meets BAV's requirements. Update only validates the identifiers against the account's format, so it can succeed for an account BAV can't run for; no check is enqueued then. Sending the values it already has changes nothing and doesn't enqueue a check.

PUT /api/cases/{caseId}/bank-accounts/{id}

Request — UK

json
{
    "sortCode": "207106",
    "accountNumber": "12345678"
}

Request — international

json
{
    "bankFields": {
        "iban": "FR1420041010050500013M02606",
        "bic": "BNPAFRPP"
    }
}

Response 204 No Content

The identifiers were saved, or already had these values.

Response 400 Bad Request

Returned if the supplied fields fail validation against the account's format. The body has the same shape as on create.

json
[
    {
        "fieldKey": "iban",
        "message": "IBAN is required."
    }
]

Response 404 Not Found

Returned if the bank account does not exist, has been deleted, or does not belong to the specified case.

Response 409 Conflict

Returned as a plain-text message in two cases. The message is the only way to tell them apart.

The account can no longer be edited because BAV has been run or requested for it:

This bank account can't be edited because bank account verification has already been run or requested. Add a new bank account instead.

The new identifiers match another bank account on the case, using the same matching rules as create. Unlike create, which returns the existing account's ID, update rejects the match and doesn't merge the accounts:

This bank account is already on the case.

Delete a bank account ​

Soft deletes a bank account. The record is retained for audit purposes but will no longer appear in list results or be eligible for BAV checks. Any existing BAV history against this account is preserved.

DELETE /api/cases/{caseId}/bank-accounts/{id}

Response 204 No Content

Response 404 Not Found

Returned if the bank account does not exist or does not belong to the specified case.