Australia BSB Number Validation

A BSB (Bank-State-Branch) number is the six-digit code that routes domestic payments to a specific branch of an Australian bank, credit union or building society. Every Australian bank account is identified by a BSB plus an account number, so a payment with a wrong BSB either fails or lands at the wrong institution.

BSB numbers are usually written as two groups of three digits, XXX-YYY. The digits break down as follows:

For example, BSB number 082-024:

  • 08 - financial institution (08 is National Australia Bank)
  • 2 - state where the branch is located
  • 024 - branch

The state digit follows a long-standing convention: 2 for New South Wales and the ACT, 3 for Victoria, 4 for Queensland, 5 for South Australia and the Northern Territory, 6 for Western Australia and 7 for Tasmania. Newer and online-only institutions often ignore it, so read the location from the state field in the API response rather than from the digit itself.

What the API checks

  • Format - the BSB must be six digits, with or without the dash. 082024 and 082-024 are treated the same; anything else returns 400 Invalid BSB.
  • Existence - the BSB must be present in the official directory. A well-formed BSB that isn't issued returns 404.

BSBs have no check digit, so a typo in a single digit often produces another well-formed number. Looking the code up in the directory is the only reliable way to catch it. Australian account numbers have no national checksum either, so the API validates the BSB but not the account number that follows it.

How to validate a BSB number

To start using our Fin Codes API sign up here and create your API key. Pass this key as a bearer token in the Authorization HTTP header, e.g. Authorization: Bearer your-api-key-here.

To validate a BSB number call /v2/bsb/{bsb_code} endpoint using HTTP client of your preference, i.e.:

curl 'https://api.fincodesapi.com/v2/bsb/082-024' \
    --header 'Authorization: Bearer your-api-key-here' \
    --header 'Accept: application/json'
# INSTALLATION
$ composer require guzzlehttp/guzzle
# REQUEST
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.fincodesapi.com/v2/bsb/082-024', [
    'headers' => [
        'Accept' => 'application/json',
        'Authorization' => 'Bearer your-api-key-here',
    ],
]);

echo $response->getBody();
# INSTALLATION
$ python -m pip install requests
# REQUEST
import requests

url = "https://api.fincodesapi.com/v2/bsb/082-024"

headers = {
    "Accept": "application/json",
    "Authorization": "Bearer your-api-key-here"
}

response = requests.request("GET", url, headers=headers)

print(response.text)
# INSTALLATION
$ npm install node-fetch --save
// REQUEST
import fetch from 'node-fetch';

const url = 'https://api.fincodesapi.com/v2/bsb/082-024';
const options = {
  method: 'GET',
  headers: {
    'Accept': 'application/json',
    'Authorization': 'Bearer your-api-key-here'
  }
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error('error:' + err));
const options = {
  method: 'GET',
  headers: {
    'Accept': 'application/json',
    'Authorization': 'Bearer your-api-key-here'
  }
};

fetch('https://api.fincodesapi.com/v2/bsb/082-024', options)
  .then(response => response.json())
  .then(response => console.log(response))
  .catch(err => console.error(err));

The response should be:

{
    "success": true,
    "data": {
        "id": "082-024",
        "branch_name": "World Square",
        "address": "Shp 10-33 Upp Gnd Lvl 686 George St",
        "suburb": "Sydney",
        "state": "NSW",
        "postcode": 2000,
        "peh": "PEH",
        "bank": {
            "id": "6ab9a942-51ca-4e5f-ab17-32612d787ed4",
            "country_id": "AU",
            "code": "NAB",
            "name": "National Australia Bank"
        }
    }
}

Response fields

  • id - the BSB, always returned in XXX-YYY form
  • branch_name, address, suburb, state, postcode - the branch's registered location
  • peh - the payment systems the BSB can be used for: P for paper (cheques), E for electronic (direct entry) and H for high-value (RTGS). A BSB without E can't receive ordinary electronic transfers.
  • bank - the institution the BSB belongs to, with its short code and full name

Common mistakes

  • Lost leading zeros - BSBs such as 012-003 (ANZ) become 12003 when a spreadsheet stores them as numbers. Keep BSBs as text when importing supplier or payroll files.
  • Old branch BSBs - when branches close or banks merge, customers may still quote the old BSB. Check the peh field to confirm the BSB still accepts electronic payments.
  • Assuming the bank from the first digit - the institution is identified by the first two or three digits, not one. Use the bank object instead of a hard-coded prefix list.

Where the data comes from

BSB data is imported from the BSB directory published by AusPayNet (Australian Payments Network), the body that allocates BSB numbers, and is refreshed weekly as branches open, close and change systems.

You can find full documentation here.