Invoice Data Extraction Logo
Invoice Data Extraction
Start Extraction
Pricing
Extraction Guide
API
Sign inCreate account
Sign inCreate account
Start Extraction
Pricing
Extraction Guide
API
  1. Home
  2. Articles & Analysis
  3. Financial Documents
  4. BAI2 File Format: Records, Codes and Validation

BAI2 File Format: Records, Codes and Validation

Learn how the BAI2 file format structures bank data. Understand record and type codes, then validate totals, counts, and continuations.

Published
Aug 30, 2026
Updated
Aug 30, 2026
Reading Time
13 min
Author
David Harding
Topics:
Financial DocumentsBank StatementsBAI2Cash Management

On this page

BAI2 is a comma-delimited bank reporting format that organizes cash-management data into nested file, group, and account records. A valid BAI2 file format transmission opens with record 01, closes with 99, and uses trailers at the account, group, and file levels to check control totals and record counts.

Banks use BAI2 to send corporate customers balance and transaction data for cash positioning, treasury operations, and reconciliation. A filename ending in .bai is a useful clue, but the contents are more reliable: the first field on each logical record is a two-digit structural code.

The hierarchy is an envelope inside an envelope:

  • File: 01 File Header opens the transmission.
    • Group: 02 Group Header opens a set of accounts from the same originator for the same reporting date and time.
      • Account: 03 Account Identifier opens one account and carries its status and summary data.
        • Transaction: optional 16 records report individual transactions.
        • Continuation: 88 extends a preceding logical record when more space or fields are needed.
      • Account close: 49 supplies the account control total and account-level record count.
    • Group close: 98 supplies the group control total, account count, and group-level record count.
  • File close: 99 supplies the file control total, group count, and total file record count.

That sequence comes directly from the BAI Cash Management Balance Reporting Specifications Version 2: 01, 02, and 03 open the file, group, and account; 16 is optional transaction detail; 49, 98, and 99 close the three levels; and 88 can continue a preceding record.

Record codes describe structure. Three-digit type codes describe the financial meaning of data within records 03 and 16, such as opening ledger balance or check paid. Record 16 and type code 165 are therefore different kinds of identifier: 16 says “transaction detail record,” while 165 identifies a preauthorized ACH credit carried by that record.

A BAI2 sample, read from header to trailer

This compact sample uses variable-length physical records, one group, one account, two transactions, and a continuation record. The sender, receiver, account, and reference identifiers are illustrative.

01,122099999,987654321,260830,0900,1,,,2/
02,987654321,122099999,1,260829,2359,USD,2/
03,0087654,USD,010,1000000,,,015,1100000,,/
16,165,150000,0,CR001,,CUSTOMER RECEIPT FOR INVOICE
88, SET 240829
16,475,50000,0,CK1001,000321,CHECK PAID
49,2300000,5/
98,2300000,1,7/
99,2300000,1,9/

The 01 line identifies the sender and receiver, gives a file creation date of 30 August 2026 and time of 09:00, assigns file ID 1, and declares Version 2. Its physical-record-length and block-size fields are defaulted, shown by the adjacent commas before the version number. That means the file uses variable-length physical records.

The 02 line opens a group. Group status 1 means update; 260829 is the as-of date; 2359 is the as-of time; USD supplies the currency; and as-of modifier 2 means final previous-day data.

The 03 line opens account 0087654. The leading zeros are part of the account number. Two repeated type-code sets report an opening ledger balance under 010 and a closing ledger balance under 015. Because USD has two implied decimal places, 1000000 represents 10,000.00 and 1100000 represents 11,000.00. The empty item-count and funds-type fields are retained with adjacent delimiters.

The first 16 line reports a type 165 preauthorized ACH credit of 1,500.00. Its text continues into 88, so neither text-bearing physical record ends with the ordinary slash delimiter. The next 16 line starts a new logical record and reports a type 475 check paid of 500.00; customer reference 000321 preserves the check-number zeros. Record 49 starts after that transaction's text and therefore marks the end of the preceding text-bearing logical record.

The three trailers close progressively wider scopes. 49 closes the account, 98 closes the group, and 99 closes the file. Their totals and counts are worked through in the validation section.

RecordNameScope and useful fields
01File HeaderOpens the file; sender, receiver, creation date and time, file ID, physical length, block size, version
02Group HeaderOpens a group; ultimate receiver, originator, status, as-of date and time, currency, date modifier
03Account Identifier and Summary/StatusOpens an account; account number, currency, repeated status or summary type-code sets
16Transaction DetailReports one transaction; detail type code, amount, funds type, bank and customer references, optional text
88ContinuationContinues the fields or text of the immediately preceding logical record
49Account TrailerCloses an account; account control total and account record count
98Group TrailerCloses a group; group control total, number of accounts, and group record count
99File TrailerCloses the file; file control total, number of groups, and total file record count

Type codes, amounts and significant zeros

BAI2 type codes are three-digit financial classifications carried inside structural records. Record 03 uses status and summary codes; each record 16 uses one detail code for one transaction. A range does not make every code valid at every level: the standard's code list designates whether an individual code is status, summary, or detail.

The main ranges are:

  • 001–099: account status codes
  • 100: total credits summary
  • 101–399: credit summary and detail codes
  • 400: total debits summary
  • 401–699: debit summary and detail codes
  • 700–799: loan summary and detail codes
  • 900–999: customized codes agreed between the parties

The custom range is not a shared vocabulary. A code in that range is meaningful only when the sender and receiver have agreed on it, and a bank may support only part of the uniform code list. Mapping work therefore needs both the base standard and the bank's implementation guide.

Type codeLevelMeaning
010StatusOpening ledger balance
015StatusClosing ledger balance
045StatusClosing available balance
100SummaryTotal credits
400SummaryTotal debits
165DetailPreauthorized ACH credit
475DetailCheck paid

Signs follow the data level, not the everyday meaning of “credit” and “debit.” An account-status amount may carry a plus or minus sign, or be unsigned with positive as the default. Summary and transaction-detail amounts may be positive or unsigned; a debit detail is not made negative merely because its type code falls in the debit range. In the sample, type 475 carries 50000, not -50000. The type code supplies the debit meaning.

Amount fields omit the decimal point. The currency code determines whether the final zero, one, two, or three digits are implied decimal places; most currencies, including USD, use two. Thus 150000 in the sample is 1,500.00 USD. Item counts are integers and do not inherit the currency's decimal convention.

Identifiers need different treatment from amounts. Both digits of record codes 01, 02, and 03 are significant, as are all three digits of status type codes. Customer account numbers are alphanumeric identifiers, so 0087654 must not become 87654. The same preservation rule should be applied to reference values such as the sample check number 000321 when a bank's specification treats them as identifiers.

Logical records, physical records and continuation rules

A physical record is the transmitted container: a run of characters occupying the declared record length, or one variable-length line when no fixed length is declared. A logical record is the meaningful BAI2 content inside that container, including its record code, fields, delimiters, and text. One logical record may span several physical records.

Record 01 controls the physical-length rule. A populated Physical Record Length field declares a fixed number of characters. When that field is defaulted, as it is in the sample, the file contains variable-length physical records. Eighty-character records are common and appear in the BAI manual's explanation, but the standard does not impose 80 characters as a universal maximum.

Outside text fields, parsing is delimiter-driven:

  • A comma separates fields.
  • Adjacent delimiters preserve a defaulted or unspecified field.
  • A slash ends a logical record that does not contain text.
  • Optional fields cannot simply disappear; their positions remain visible through adjacent delimiters.

Text changes the termination rule because a text field may contain commas or slashes after its first character. A parser cannot treat the first slash or comma in that text as the end of the record. Instead, the logical record continues until the next record that is not an 88 continuation begins.

Record 88 may continue any preceding record type, including another 88. When continuation occurs between ordinary fields, the preceding non-text field must be completed in its physical record; the next field starts in the 88 record. A non-text field cannot be split across physical records. Text is the exception and may break inside the field, with no slash placed at the physical boundary.

In the sample, the first 16 begins a text field containing CUSTOMER RECEIPT FOR INVOICE. The following 88 begins with a space before SET 240829, so preserving that space produces the combined text CUSTOMER RECEIPT FOR INVOICE SET 240829. The next 16 ends the logical record formed by those two physical records. The second 16 also ends in text, so its logical record ends when 49 begins. A parser that treats each newline as a complete logical record would detach the continuation; one that splits every line at slash would mishandle valid text containing that character.

How to validate BAI2 totals and record counts

Validation works from the account outward. Start with each 49 trailer, then verify its enclosing 98, and finish with 99. This isolates a failure to the smallest envelope instead of treating the entire file as one undifferentiated mismatch.

For the sample account, the 49 control total is the algebraic sum of every Amount field in the preceding 03 and its associated 16 and 88 records. Funds Type amounts and item counts are excluded:

1000000 + 1100000 + 150000 + 50000 = 2300000

The account count is 5 records: one 03, two 16 records, one 88, and the closing 49 itself. The enclosing 02 does not belong to the account count.

The 98 group trailer adds the control totals from all accounts in the group. This sample has one account, so its group control remains 2300000. Its account count is 1, and its group record count is 7: the 02 header, five account-level records, and the 98 trailer.

The 99 file trailer adds all group control totals. With one group, the file control is again 2300000. The group count is 1, and the total file count is 9: the 01 header, all seven group records, and the closing 99.

A control total is a transmission check, not a net cash calculation. The type 475 debit amount contributes +50000 to the sample's control total because detail amounts are transmitted as positive or unsigned. The independent financial equation uses the code's meaning instead:

Opening ledger 1000000 + credit 150000 - debit 50000 = closing ledger 1100000

Structural validity therefore does not prove that a balance is economically correct or matched to the ledger. It establishes that the reported amount fields and records foot to their trailers. The bank statement reconciliation process then compares the bank activity with internal books and investigates timing or posting differences.

Common failures point to distinct parsing or mapping defects:

  • Record count is low: an 88, header, or trailer was excluded from the relevant scope.
  • Record count is high: a text continuation was split into invented logical records, or a record was duplicated during transfer.
  • Account control does not foot: a status or summary Amount in 03 was skipped, a detail amount was negated from its debit code, or a Funds Type distribution was incorrectly included.
  • Group or file control fails while accounts pass: an account or group was omitted from the higher-level sum.
  • Hierarchy fails: a 49, 98, or 99 is missing or duplicated, or an 88 appears without a record to continue.
  • Values change after import: leading zeros were stripped, implied decimals were applied to item counts, or the wrong currency precision was used.
  • Codes are rejected: the bank uses a proprietary code or supported subset not covered by the receiving system's map.
  • A bank file differs from the baseline: padding, grouping, optional-field population, and control behavior must be checked against that bank's implementation guide before being labeled invalid.

BAI2, BTRS, MT940, CAMT.053 and CODA compared

These formats solve related bank-reporting problems, but their visible grammar and governing standards differ. A system that accepts one should not be assumed to accept another, even when the files carry equivalent balances and transactions.

FormatGovernance and contextSyntax and identification cues
BAI2BAI Version 2; long-established corporate reporting with a North American center of gravity and documented use by Australasian banksFlat text with comma-delimited fields; two-digit records such as 01, 02, 03, 16, and 99
BTRSX9.121, the modernized successor associated with BAI2Retains BAI2's record architecture while adding UTF-8 support and more structured Record 88 remittance handling; confirm the stated X9.121 version and bank guide
MT940SWIFT customer statement message used across many corporate banking relationshipsTagged plain text, readily identified by fields such as :20:, :25:, :61:, and :86:
CAMT.053ISO 20022 bank-to-customer statement messageXML with named elements, namespaces, and a nested document structure rather than numeric line records
CODABelgian bank statement standardCoded fixed-layout records used in Belgian banking, distinct from BAI2's comma-delimited grammar

ASC X9 describes the Balance and Transaction Reporting Standard as formerly BAI2 and identifies X9.121 BTRS Version 3 as a modernized format. That lineage does not make the names interchangeable for implementation. A bank may say “BAI2,” “BTRS,” or “BAI2/BTRS” while supporting a particular record layout, code-list revision, or proprietary subset. The bank's specification and the receiving system's declared version are decisive.

MT940 and CAMT.053 are easier to distinguish visually. MT940 is tag-based text, while CAMT.053 is XML. The deeper differences in hierarchy, remittance detail, and implementation are covered in the guide to MT940 and CAMT.053 bank statement formats. CODA is another country-specific family; its numbered fixed-layout records are covered in the Belgian CODA bank statement format.

BAI2 is most closely associated with North American corporate banking, but it is not strictly US-only. Banks in Australia and New Zealand also document BAI2 reporting services. Geography narrows the likely format; the record grammar and the bank's implementation document identify it.

Invoice Data Extraction

Extract data from invoices and financial documents to structured spreadsheets. 50 free pages every month — no credit card required.

Try It Free
Continue Reading

Related Articles

Explore adjacent guides and reference articles on this topic.

How to Convert a FAB Bank Statement to Excel

Learn when to export a FAB report or convert a PDF statement to Excel, with a UAE-ready field schema, privacy tips and balance checks.

How to Convert Revolut Statements to Excel

Convert Revolut PDF, Excel or CSV statements into clean accounting-ready spreadsheets, with multi-currency columns for Xero, QuickBooks and bookkeeping.

Convert Permanent TSB (Open24) Statements to Excel

Convert Permanent TSB (Open24) exports and PDF eStatements into clean Excel or CSV — a practical guide for Irish sole traders, bookkeepers and accountants.

Back to Articles & Analysis

Invoice Data Extraction

The AI-native automation platform for high-accuracy invoice extraction

Platform

  • Start Extraction
  • Home
  • Pricing
  • API
  • Python SDK
  • Node.js SDK

Solutions

  • Invoice to Excel
  • Invoice OCR Software
  • Bank Statement Converter
  • Receipt OCR
  • Utility Bill Extraction
  • Payroll Data Extraction
  • PDF Data Extraction

Resources

  • Articles
  • Contact

Trust & Security

  • Security
  • Subprocessors
  • AI Data Use

Legal

  • Terms of Service
  • Data Processing Addendum
  • Privacy Policy
  • Refund Policy
  • US State Privacy Rights
  • EEA/UK Privacy Rights
English
Sign inCreate account

© 2026 Invoice Data Extraction — DEH Technologies LLC

Secure by Design. Your data is never used for AI training.