Bacs Standard 18 File Format Explained

Long before JSON and XML, payment instructions were exchanged as rigidly formatted text files where the meaning of a value depended entirely on which character position it occupied. The UK's Standard 18 format is a living example: it still carries millions of Bacs Direct Debits and Direct Credits every working day. Understanding its structure is a rite of passage for anyone integrating with Bacs, and a useful window into how legacy rails encode money.
Fixed-width thinking
Standard 18 is a fixed-width format: every record is exactly 100 characters, and each field lives at a defined offset and length. There are no delimiters between fields; a parser reads columns, not commas. This makes the format compact and unambiguous to machines of the era, but utterly unforgiving — a value one character too long, or padded with the wrong character, corrupts everything after it. Amounts, for example, are expressed in pence, right-justified and zero-padded, with no decimal point.
The label records
A Standard 18 file is not just rows of payments; it is wrapped in label records that describe and bound the data. These labels trace back to magnetic-tape conventions and include:
- VOL1 – the volume header, identifying the submitting party.
- HDR1 and HDR2 – header labels marking the start of a file section and describing the dataset, including the file/section identifiers and processing dates.
- UHL1 – the user header label, which carries the intended processing date (in a day-of-year style value) and work type.
- EOF1, EOF2 and UTL1 – trailer labels marking end-of-file and carrying control totals.
These labels let the receiving system verify it has a complete, correctly bounded file before it trusts a single payment inside.
The payment data records
Between the headers and trailers sit the actual instruction records, each 100 characters. Key fields in a data record include:
- Destination sort code and account number – the account being debited or credited.
- Transaction code – a two-character code defining what the record does. For example, 01 is a first Direct Debit collection, 17 a regular Direct Debit, 18/19 represent re-presentation and final collections, 99 a Direct Credit, and 0C/0N/0S relate to AUDDIS new-instruction and cancellation records. The code tells the paying bank exactly how to treat the row.
- Originating sort code and account – the Service User's collecting or paying account.
- Amount – in pence, zero-padded.
- Service User Number (SUN), reference and name fields – identifying the collector and giving the payer a reference on their statement.
Contra records and control totals
Files include contra records — balancing entries that represent the total credit or debit to the Service User's own account for a set of transactions — so that the file is internally self-balancing. The trailer's control totals (record counts and summed values) must reconcile exactly; a mismatch causes the whole submission to be rejected rather than partially processed. This all-or-nothing validation is characteristic of batch file rails.
Submission and why it persists
Standard 18 files are typically signed and transmitted through Bacstel-IP using smart-card-based authentication, often via approved bureau software. Despite its age, the format endures because it is deeply embedded: thousands of billers, accounting packages, and bank systems speak it fluently, and Bacs volumes are enormous. Migrating a national batch rail to a modern message standard is a multi-year undertaking, so for now Standard 18 remains the format anyone collecting UK Direct Debits must generate correctly — padding, offsets, transaction codes, and all.
Common integration mistakes
Because the format is unforgiving, the same errors trip up newcomers repeatedly. Padding mistakes top the list: amounts must be zero-padded and right-justified, while text fields are space-padded and left-justified, and mixing these corrupts field alignment. Date encoding is another trap — the processing date in the UHL1 label uses a Julian-style day format that is easy to compute wrongly, causing files to be processed on the wrong day or rejected. Control-total drift, where the trailer totals do not exactly match the summed records, guarantees rejection of the whole file. And forgetting the balancing contra record leaves the submission unbalanced. Validating a generated file against the specification before transmission, ideally with test files through the scheme's testing service, catches these before they become failed collections.
Key takeaways
- Standard 18 is a fixed-width format with 100-character records and no field delimiters.
- Label records (VOL1, HDR, UHL1, EOF/UTL) bound the file and carry the processing date and control totals.
- Each payment record uses a two-character transaction code (e.g. 01, 17, 99) to define its purpose.
- Amounts are in pence, zero-padded, with contra records making the file self-balancing.
- Files are submitted via Bacstel-IP; control totals must reconcile exactly or the whole file is rejected.