Bank account

Brazilian bank account (agência, conta and dígito) check-digit validation, per bank.

  • Parity matrix

Validate

Validates a Brazilian bank account (bank code, agency, account and check digit).

  • bankCode, agency and account have every non-digit character removed ("1-584" and "0021.0169" are read as digits). digit is uppercased and keeps only digits, P and X. A value that is not an object, or a field that is not a string, makes the account invalid.
  • params carries bankCode (3 digits), agency (1 to 5 digits), account (1 to 13 digits) and digit (1 or 2 characters, or X for Banco do Brasil and P for Bradesco), all strings.
  • bankCode must be a Banco Central STR participant (the list that bank.getByCode uses). The function rejects any other code.
  • Nine banks are checked with a check-digit rule, each with its own agency and account lengths (digit is one character):
    • Banco do Brasil (001): agency 4 to 5 digits, account 8 to 10 digits. Modulus 11 over the account, weights 2 to 9 cycling from the right; a result of 10 gives X.
    • Santander (033): agency 4 digits, account 8 digits. Over agency + 00 + account, weights 9,7,3,1,0,0,9,7,1,3,1,9,7,3, keeping only the units digit of each product; the digit is (10 - sum mod 10) mod 10.
    • Banrisul (041): agency 4 digits, account 9 digits (tipo 2 digits + conta 7 digits). Weights 3,2,4,7,6,5,4,3,2 over the account, modulus 11; remainder 0 gives 0, remainder 1 gives 6, otherwise 11 minus the remainder.
    • Caixa (104): agency 4 digits, account 11 or 12 digits. See below.
    • Bradesco (237): agency 4 digits, account 7 digits. Modulus 11 over the account, weights 2 to 7 cycling from the right; a result of 10 gives P.
    • Nubank (260): agency 4 digits, account 5 to 13 digits. Verhoeff digit over the account with leading zeros dropped.
    • Itaú (341): agency 4 digits, account 5 digits. Modulus 10 over agency + account.
    • HSBC/Kirton (399): agency 4 digits, account 6 digits. Weights 8,9,2,3,4,5,6,7,8,9 over agency + account, modulus 11; remainder 10 gives 0.
    • Citibank (745): agency 4 digits, account 10 digits. Weights 11,10,9,8,7,6,5,4,3,2 over the account, modulus 11; remainder 0 or 1 gives 0, otherwise 11 minus the remainder.
  • No act of the Banco Central, of another government body or of FEBRABAN sets these rules. The FEBRABAN CNAB 240 layout (v11.0, notes G009 to G012) calls each check digit a "código adotado pelo Banco" and gives no algorithm.
  • Official source (the bank's own layout manual): Caixa (both digits, CNAB 400 notes NE051/NE052 and CNAB 240 note G011), Santander (the account digit, Débito Automático 150 positions v08, April 2026) and Banco do Brasil (the agency digit, Doc5175 Anexo XI; the manual only calls the account digit "módulo 11", which matches the rule here). The rules here match their worked examples.
  • Third-party compendium: the other rules (Banrisul, Bradesco, Itaú, HSBC/Kirton, Citibank and the Caixa 11-digit form) follow the Icatu Seguros compendium "Regras de Validação de dígito verificador de agência e conta corrente", a private compilation. Nubank publishes no rule; its Verhoeff digit comes from open-source validators that derived it from real accounts.
  • Caixa (104): the agency has 4 digits and the digit is 1 character. A 12-digit account (the "sem operação" form of the Caixa layouts) accepts either of the two Caixa digits: the account digit over the 12 digits (official example: 000000109990 gives 6) or the agency/account digit (0161 + 000000109990 gives 5). Both are modulus 11 with weights 2 to 9 from the right, a result above 9 giving 0. The older 11-digit form, operação (3 digits) + conta (8 digits), keeps the compendium's agency/account rule. 2.4.0 rejected a 12-digit Caixa account.
  • These banks are checked by structure only, because no check-digit rule of theirs is known: Inter (077), Ailos (085), XP (102), Unicred (136), Stone (197), BTG Pactual (208), Original (212), PagBank (290), BMG (318), Mercado Pago (323), C6 (336), PicPay (380), Cora (403), Pan (623), BV (655), Daycoval (707), Sicredi (748) and Sicoob (756). Agency (1 to 5 digits) and account (1 to 13 digits) only need to fit their lengths, and a single numeric digit is enough (X and P are not accepted).
  • Every other listed bank uses a generic fallback: a 1-character digit must equal the mod 10, the boleto mod 11 or the bank mod 11 of the account, so up to three of the ten digits pass for a given account. A 2-character digit chains mod 10 then mod 11. No published rule backs the fallback: true for a bank outside the lists above says the structure is plausible, not that the check digit is proven.
  • For Banco do Brasil the agency digit is not checked. A 5-digit agency (1584-9) is only held to the length, whatever its last digit is.
ParameterTypeRequired
paramsIsValidBankAccountParamsyes
params.bankCodestringyes
params.agencystringyes
params.accountstringyes
params.digitstringyes
returnsboolean

Check if a Brazilian bank account is valid. The bankCode must be a Banco Central STR participant (the list getBankByCode uses).

  • Params (IsValidBankAccountParams, all strings): bankCode (3 digits), agency (1-5 digits), account (1-13 digits) and digit (1-2 characters, or X for Banco do Brasil and P for Bradesco).
  • A listed bank is validated in one of three ways: by a check digit rule, by structure only, or by a generic mod10/mod11 fallback.
  • No act of the Banco Central, of another government body or of Febraban sets these check digit rules. Those of banks 001, 033, 041, 104, 237, 341, 399 and 745 come from the "Regras de Validação de dígito verificador de agência e conta corrente" compendium of Icatu Seguros, a private compilation of each bank's rule. Nubank publishes no rule: its Verhoeff digit is the one open source validators derived from real accounts.
  • Three banks publish their own rule in their layout manuals, and the rules here match them: the Caixa both of its digits over a 12 digit account (notes NE051 and NE052), Santander the account digit (Débito Automático 150 v08, April 2026), and Banco do Brasil only the agency digit (Anexo XI), its account digit being only "módulo 11".
  • The only official texts on these digits say there is no common rule: the FEBRABAN Layout Padrão CNAB 240 v11.0 (11/09/2026), notes G009, G011 and G012, calls each of them a "código adotado pelo Banco" and gives no algorithm, and the DICT API of the Banco Central takes the account with its digit and computes nothing.

Banks validated by a check digit rule:

BankCodeAgencyAccountNotes
Banco do Brasil0014-5 digits8-10 digitsmod11 with weights 2..9 cycling from the right; digit may be "X"
Santander0334 digits8 digitsweights 9,7,3,1,0,0,9,7,1,3,1,9,7,3 over agency + "00" + account, tens discarded
Banrisul0414 digits9 digitsweights 3,2,4,7,6,5,4,3,2; remainder 0 gives 0 and remainder 1 gives 6; account is tipo (2 digits) + conta (7 digits)
Caixa Econômica Federal1044 digits11-12 digitsmod11 with weights 2..9 cycling from the right, a result above 9 giving 0. A 12 digit account (the format of the Caixa layouts, "sem operação") takes either its own digit (over the account) or the agency/account one (over agency + account); an 11 digit one is operação (3 digits) + conta (8 digits), with the digit over agency + account. Up to 2.4.0 a 12 digit account was rejected
Bradesco2374 digits7 digitsmod11 with weights 2..7 cycling from the right; remainder 0 gives 0 and remainder 1 gives "P"
Nubank2604 digits5-13 digitsVerhoeff check digit over the account, leading zeros dropped (no published rule; see above)
Itaú Unibanco3414 digits5 digitsmod10 over agency + account
HSBC / Kirton Bank3994 digits6 digitsweights 8,9,2,3,4,5,6,7,8,9 over agency + account; remainder 10 gives 0
Citibank7454 digits10 digitsweights 11..2 over the account; remainder 0 or 1 gives 0

Banks validated by structure only, since no check digit rule of theirs is known (a single numeric digit is enough):

BankCodeBankCode
Inter077Mercado Pago323
Ailos085C6336
XP102PicPay380
Unicred136Cora403
Stone197Pan623
BTG Pactual208BV655
Original212Daycoval707
PagBank290Sicredi748
BMG318Sicoob756
  • Every other listed bank uses the generic fallback: digit must match mod10 or mod11 over the account. A 2 character digit chains mod10 then mod11. No published rule backs it and up to three of the ten digits pass for a given account, so true for a bank outside the tables above says the structure is plausible, not that the check digit is proven.
  • For Banco do Brasil the agency digit is not checked: a 5 digit agency (1584-9) is only held to the length, whatever its last digit is.
import { isValidBankAccount } from '@brazilian-utils/brazilian-utils';

isValidBankAccount({
  bankCode: '001',
  agency: '1584',
  account: '00210169',
  digit: '6'
}); // true (Banco do Brasil)

isValidBankAccount({
  bankCode: '341',
  agency: '2545',
  account: '02366',
  digit: '1'
}); // true (Itaú)

isValidBankAccount({
  bankCode: '104',
  agency: '0647',
  account: '00188888888',
  digit: '7'
}); // true (Caixa: operação "001" + conta "88888888")

isValidBankAccount({
  bankCode: '041',
  agency: '2664',
  account: '358507670',
  digit: '6'
}); // true (Banrisul: tipo "35" + conta "8507670")

isValidBankAccount({
  bankCode: '260',
  agency: '0001',
  account: '5216125',
  digit: '0'
}); // true (Nubank, Verhoeff)

isValidBankAccount({
  bankCode: '077',
  agency: '0001',
  account: '123456789',
  digit: '0'
}); // true (Banco Inter, structure only)

isValidBankAccount({
  bankCode: '077',
  agency: '0001',
  account: '123456789',
  digit: 'X'
}); // false (a structure only bank still requires a numeric digit)

isValidBankAccount({
  bankCode: '999',
  agency: '1234',
  account: '123456',
  digit: '6'
}); // false (999 is not a Banco Central participant)

isValidBankAccount({
  bankCode: '246',
  agency: '1234',
  account: '123456',
  digit: '6'
}); // true (Banco ABC Brasil, generic mod10 fallback)

Source: STR participants list (official). Based on: the Icatu Seguros compendium Regras de Validação de dígito verificador de agência e conta corrente and, for Nubank, bran_checker.

Code: brazilian-utils/javascript
Try it with JavaScript isValidBankAccount
The inputs start with the first shared case. Change one to see the new result.

Runs @brazilian-utils/brazilian-utils 2.5.0 in your browser.

Shared test cases (143) and the result in each library bankAccount.isValid

Official sources

See also Banks

Last updated on

On this page