# ABR API Research Notes

> Last updated: 2025-02-05  
> Status: **Implementation complete** — code written, needs ABR_GUID to go live

## Overview

The Australian Business Register (ABR) provides free web services to look up ABN details.
Two flavours exist: a SOAP/XML service and a lightweight JSON (JSONP) service.
We chose **JSON** for simplicity — zero extra dependencies.

---

## JSON API (what we use)

| Endpoint | URL |
|----------|-----|
| ABN Lookup | `https://abr.business.gov.au/json/AbnDetails.aspx?abn={ABN}&callback={cb}&guid={GUID}` |
| ACN Lookup | `https://abr.business.gov.au/json/AcnDetails.aspx?acn={ACN}&callback={cb}&guid={GUID}` |
| Name Search | `https://abr.business.gov.au/json/MatchingNames.aspx?name={NAME}&maxResults=10&callback={cb}&guid={GUID}` |

**Format:** JSONP — response is wrapped like `callback({...})`. Strip the wrapper to get pure JSON.

### ABN Lookup Response Shape

```jsonc
{
  "Abn": "74172177893",
  "AbnStatus": "Active",
  "AbnStatusEffectiveFrom": "01 Jan 2023",
  "Acn": "172177893",
  "AddressDate": "2023-01-15",
  "AddressPostcode": "2000",
  "AddressState": "NSW",
  "BusinessName": ["Trading Name 1", "Trading Name 2"],
  "EntityName": "EXAMPLE PTY LTD",
  "EntityTypeCode": "PRV",
  "EntityTypeName": "Australian Private Company",
  "Gst": "01 Jul 2000",     // null if not GST-registered
  "Message": ""               // non-empty = error/not-found
}
```

### Error Responses

When something goes wrong, `Message` contains the error text and entity fields are empty:
- `"The GUID entered is not recognised as a Registered Party"` — bad/missing GUID
- `"Search text is not a valid ABN or ACN"` — malformed input
- `""` with empty Abn — no records found

---

## XML/SOAP API (not used, for reference)

| Endpoint | URL |
|----------|-----|
| Latest ABN search | `https://abr.business.gov.au/abrxmlsearch/abrxmlsearch.asmx/SearchByABNv202001` |
| WSDL | `https://abr.business.gov.au/abrxmlsearch/abrxmlsearch.asmx?WSDL` |

Parameters: `searchString={ABN}&includeHistoricalDetails=N&authenticationGuid={GUID}`

Returns XML `<ABRPayloadSearchResults>` with `<businessEntity>` or `<exception>`.

---

## Authentication

- **Type:** GUID (Globally Unique Identifier)
- **Cost:** Free
- **Registration:** https://abr.business.gov.au/Tools/WebServicesAgreement
  1. Read & accept the Web Services Agreement
  2. Fill in registration form
  3. Receive GUID via email (usually within minutes)
- **Storage:** `ABR_GUID` environment variable (never expose client-side)
- **Note:** `api.gov.au` is unrelated — it's a design standard site, not a key provider

---

## ABN Validation Algorithm

Source: https://abr.business.gov.au/Help/AbnFormat

An ABN is 11 digits: 2 check digits + 9-digit identifier.

1. Subtract 1 from the first digit
2. Multiply each digit by its positional weight:
   ```
   Position:  1   2   3   4   5   6   7    8    9   10   11
   Weight:   10   1   3   5   7   9  11   13   15   17   19
   ```
3. Sum all 11 products
4. If `sum % 89 === 0` → valid

**Worked example:** `51 824 753 556`
- After step 1: `41 824 753 556`
- Sum: 40+1+24+10+28+63+55+39+75+85+114 = **534**
- 534 ÷ 89 = 6 remainder **0** ✓

---

## Implementation

### Files Created

| File | Purpose |
|------|---------|
| `src/lib/abn-utils.ts` | ABN validation (mod-89 checksum), formatting, cleaning |
| `src/app/api/abn-lookup/route.ts` | Next.js API route — GET `/api/abn-lookup?abn=...` |

### API Route Behaviour

```
GET /api/abn-lookup?abn=51824753556

→ 200  { success: true, data: { name, abn, status, state, postcode, type, gstRegistered, ... } }
→ 400  { success: false, error: "Invalid ABN — must be 11 digits with valid checksum" }
→ 404  { success: false, error: "ABN not found ..." }
→ 502  { success: false, error: "Failed to reach the Australian Business Register..." }
→ 503  { success: false, error: "ABR API not configured..." }
```

### Dependencies
- **None extra** — uses native `fetch` and string parsing (JSONP → JSON)
- `xml2js` is NOT needed (we use the JSON endpoint, not SOAP)

### To Go Live
1. Register for ABR web services GUID
2. Add `ABR_GUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` to `.env.local`
3. Deploy

---

## Test ABNs (from ABR docs)

| Description | ABN |
|-------------|-----|
| Suppressed ABN | 34 241 177 887 |
| Replaced ABN | 30 613 501 612 |
| Re-issued ABN | 40 348 075 953 |
| Multiple addresses | 33 531 321 789 |
| Multiple GST status | 76 093 555 992 |
| Many name types | 97 047 258 128 |
| Superannuation fund | 12 586 695 715 |
