⚡ Node.js🇦🇺 AustraliaTax Compliance

Australian Business Compliance — ABN & GST Validation

Validate Australian Business Numbers (ABN) in Node.js. Check GST registration status, retrieve entity names and types from the ABR, and run batch validations with Promise.all.

Also available in Python

1. ABN structure

An ABN is an 11-digit number issued by the Australian Business Register (ABR). It includes a 2-digit check prefix and the entity's 9-digit identifier.

ABN: 51 824 753 556
       ^^              check digits (mod-89 weighted sum)
          ^^^^^^^^^    unique entity identifier
ℹ️ABNs are publicly searchable on the ABR. The /v0/abn endpoint validates format and checksum, and enriches results with ABR registry data (entity name, GST status, etc.).

2. Validate an ABN

Endpoint: GET /v0/abn?value=…

{
  "valid": true,
  "abn": "51824753556",
  "formatted": "51 824 753 556",
  "found": true,
  "entityName": "Example Pty Ltd",
  "entityType": "Australian Private Company",
  "abnStatus": "Active",
  "abnStatusFrom": "2001-01-01",
  "acn": "824753556",
  "state": "NSW",
  "postcode": "2000",
  "gstRegistered": true,
  "businessNames": ["Example Trading", "Example Services"],
  "dataSource": "ABR"
}
  1. Check valid — mod-89 weighted checksum
  2. Check found — located in ABR registry
  3. Check abnStatus === "Active"
  4. Use formatted (XX XXX XXX XXX) in invoices

3. GST registration check

Businesses with annual turnover above AUD 75,000 must register for GST. Check gstRegistered to determine whether to charge GST on invoices.

const result = await iv.abn(abnNumber)
if (!result.gstRegistered) {
  // Supplier is not registered for GST
  // Cannot claim GST input tax credits from this supplier
  console.warn('Supplier not GST-registered — no input tax credits applicable')
}
⚠️Not all valid ABNs are GST-registered. Small businesses below the AUD 75,000 threshold may have a valid active ABN but no GST registration.

4. Entity name and type lookup

const result = await iv.abn(abnNumber)
if (result.found) {
  // Pre-fill company name in onboarding form
  console.log(`Entity: ${result.entityName}`)         // "Example Pty Ltd"
  console.log(`Type: ${result.entityType}`)           // "Australian Private Company"
  console.log(`ABN active since: ${result.abnStatusFrom}`) // "2001-01-01"
  console.log(`Trading names: ${result.businessNames?.join(', ')}`)
}

5. Batch validation with Promise.all

import { createClient } from '@isvalid-dev/sdk'

const iv = createClient({ apiKey: process.env.ISVALID_API_KEY! })

interface AbnValidationResult {
  valid: boolean
  abn: string
  formatted: string
  found: boolean
  entityName?: string
  entityType?: string
  abnStatus?: string
  abnStatusFrom?: string
  acn?: string
  state?: string
  postcode?: string
  gstRegistered?: boolean
  businessNames?: string[]
  dataSource?: string
}

async function validateAbn(abn: string): Promise<AbnValidationResult> {
  const result = await iv.abn(abn)

  if (!result.valid) {
    throw new Error(`Invalid ABN format: ${abn}`)
  }

  if (!result.gstRegistered) {
    console.warn(`ABN ${result.formatted} is not registered for GST`)
  }

  return result
}

async function validateBatch(abns: string[]) {
  const results = await Promise.allSettled(abns.map(a => iv.abn(a)))
  return abns.map((abn, i) => ({
    abn,
    result: results[i].status === 'fulfilled' ? results[i].value : null,
    error: results[i].status === 'rejected' ? results[i].reason?.message : null,
  }))
}

// Example
const result = await validateAbn('51824753556')
console.log(`Entity: ${result.entityName}`)
console.log(`GST registered: ${result.gstRegistered}`)
console.log(`State: ${result.state}, Postcode: ${result.postcode}`)

6. ACN extraction

For companies (Pty Ltd, Ltd), the ABN embeds the 9-digit ACN (Australian Company Number).

const result = await iv.abn(abnNumber)
if (result.acn) {
  // ACN is the last 9 digits of the ABN for companies
  console.log(`ACN: ${result.acn}`)   // "824753556"
  // Format as XXX XXX XXX for display
  const formattedAcn = result.acn.replace(/(d{3})(d{3})(d{3})/, '$1 $2 $3')
}

7. Edge cases

ABN cancelled or deregistered

⚠️An ABN can have a valid checksum but be cancelled. Always check abnStatus === "Active" in addition to valid.
const result = await iv.abn(abn)
if (result.valid && result.found && result.abnStatus !== 'Active') {
  throw new Error(`ABN is not active: status is ${result.abnStatus}`)
}

ABN not found in registry

if (result.valid && !result.found) {
  // Checksum passes but ABR has no record
  // Treat as invalid for compliance purposes
  console.warn('ABN not found in ABR — may be recently issued or test number')
}

Sole traders — no ACN

ℹ️Sole traders and partnerships have ABNs but no ACN. The acn field will be absent or null for these entity types.

8. Summary checklist

Validate ABN format via mod-89 checksum
Check found flag for ABR registry presence
Require abnStatus === "Active"
Check gstRegistered before issuing tax invoices
Use formatted (XX XXX XXX XXX) on documents
Extract ACN from ABN for company registrations
Run batch lookups with Promise.allSettled
Handle sole traders gracefully (no ACN)

See also

Ready to integrate?

Free tier — 1,000 requests/month. No credit card required.

Get your API key →