Documentation

WattleAddr API

Add Australian address autocomplete, verification and geocoding to any application. Base URL https://api.wattleaddr.com.au/v1. JSON only. Australian addresses only.

Build in 60 seconds. The whole API is described in an interactive reference you can call live, or take the machine-readable spec into your own tools:Paste the spec URL into Swagger UI, Scalar, Stoplight, Postman, or an OpenAPI client generator to scaffold an SDK in your language.

Quickstart

Grab a secret key from the console, then make your first call. This works as-is once you paste your key in:

# 1. suggestions as someone types (not billed)
curl -s -H "Authorization: Bearer waddr_sk_live_…" \
  "https://api.wattleaddr.com.au/v1/addresses/autocomplete?q=1+martin+pl"

# 2. retrieve the one they picked (this is the billable lookup)
curl -s -H "Authorization: Bearer waddr_sk_live_…" \
  "https://api.wattleaddr.com.au/v1/addresses/GANSW706124693"

Or drop in the browser widget

One script tag, no build step, no dependencies. Use a publishable key (waddr_pk_…) locked to your domains in the console. It handles session tokens for you, so all the keystrokes behind one address count as a single billable lookup.

<input id="address" />
<script src="https://api.wattleaddr.com.au/v1/widget.js"></script>
<script>
  const wa = new WattleAddr('waddr_pk_live_…');
  wa.attach('#address', {
    onSelect: (a) => console.log(a.formatted, a.components, a.geo)
  });
</script>
OptionDefaultWhat it does
onSelectrequiredCalled with the full record once someone picks an address.
onErrorconsole warningCalled instead of logging, if you want to handle failures yourself.
themelightlight, dark, or auto to follow the visitor’s system setting.
limit6How many suggestions to show.
stateallRestrict to one state, for example NSW.

Or install the SDK from npm

Official, typed, MIT-licensed packages. Use @wattleaddr/react for React, or the zero-dependency @wattleaddr/js for vanilla JavaScript or server-side Node.

# React: useAddressAutocomplete hook + <AddressAutocomplete> component
npm install @wattleaddr/react

# Vanilla JS / Node: headless client + the same drop-in widget
npm install @wattleaddr/js

The React component drops into any form. Use a publishable key:

import { AddressAutocomplete } from '@wattleaddr/react';

<AddressAutocomplete
  apiKey="waddr_pk_live_…"
  onSelect={(a) => console.log(a.formatted, a.components.postcode)}
/>

Or call it headlessly with the client — it runs in the browser and in Node 18+. On the server, set keyTransport: 'header' to send a secret key as a Bearer token instead of in the URL:

import { WattleAddrClient, createSession } from '@wattleaddr/js';

const client = new WattleAddrClient('waddr_sk_live_…', { keyTransport: 'header' });
const session = createSession();
const { suggestions } = await client.autocomplete('1 mart', { session });
const addr = await client.retrieve(suggestions[0].id, { session }); // the billable call

Building with a coding agent

If you use Claude Code, Cursor, Copilot or similar, give it our agent skill. It covers the things an assistant otherwise gets wrong — session tokens and what they cost, which key belongs in the browser, PO Boxes being absent from G-NAF by design, reading a verify verdict, and how to store the address components. It is a single markdown file with no telemetry.

# any assistant: fetch it into your project
curl -o WATTLEADDR.md https://wattleaddr.com.au/skills/wattleaddr/SKILL.md

# Claude Code: drop it in as a skill
mkdir -p .claude/skills/wattleaddr && curl -o .claude/skills/wattleaddr/SKILL.md \
  https://wattleaddr.com.au/skills/wattleaddr/SKILL.md

It also ships inside @wattleaddr/js, at node_modules/@wattleaddr/js/skills/wattleaddr/SKILL.md, so an agent working in a project that already depends on the SDK can find it without downloading anything.

Authentication

Two key types, both created in the console. Never expose a secret key in the browser.

KeyPrefixWhereSecured by
Secretwaddr_sk_live_…Server-sideAuthorization: Bearer + optional IP allowlist
Publishablewaddr_pk_live_…BrowserAllowed referrer domains + rate limits

That is how your application authenticates. How your team signs in to the console is separate: on Enterprise plans you can point it at your own identity provider over OpenID Connect, and require it. See single sign-on setup.

Endpoints

MethodPathPurpose
GET/v1/addresses/autocompleteType-ahead suggestions for a partial query
GET/v1/addresses/{id}Full structured record for a chosen suggestion (billable)
POST/v1/addresses/verifyMatch free-text to the best canonical address, with a per-field verdict (billable on a match)
GET/v1/statusService health & current G-NAF release

Example: autocomplete

curl "https://api.wattleaddr.com.au/v1/addresses/autocomplete?q=1+martin+pl+sydney&session=abc" \
  -H "Authorization: Bearer waddr_sk_live_…"
{
  "suggestions": [
    { "id": "GANSW706124693", "formatted": "1 Martin Place, Sydney NSW 2000" }
  ]
}

Example: verify, and what a verdict means

verify takes free text you already hold and returns the best canonical match plus an assessment of how well it answers what you sent. Branch on verdict.

curl "https://api.wattleaddr.com.au/v1/addresses/verify" \
  -H "Authorization: Bearer waddr_sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"address": "100 collins st melbourne", "session": "abc"}'
{
  "matched": true,
  "match": { /* the full canonical record */ },
  "verdict": "corrected",
  "match_score": 75,
  "match_level": "premise",
  "elements": { "street_number": "verified", …, "postcode": "missing" },
  "changed_elements": []
}
verdictMeaningHandling
verifiedEvery element you supplied agrees, and no other candidate fitsAccept
correctedAgrees as far as it goes — you abbreviated or left something outAccept the canonical form, or re-prompt for the missing elements
ambiguousAn element was contradicted, input was discarded, or a runner-up fits equally wellReview — never auto-accept
unverifiedNothing matched, or the match scored too low to rely onReject and flag

elements gives every field its own status — verified, changed or missing — so a checkout can re-prompt for the one field that is wrong instead of the whole address. match_level says how precisely we identified it (subpremisepremise thoroughfarelocality) and is independent of the verdict. We publish no accept/reject score threshold: the right line depends on what a wrong address costs you, and a single number cannot say “we matched a building on a street whose suburb you contradicted”. The older top-level confidence field is deprecated — it is still returned, but it was a constant on any match before August 2026, so branch on verdict instead. This tells you an address exists in G-NAF and where it is — not that mail can be delivered to it.

PO Boxes & postal addresses

G-NAF is a register of physical addresses, so it contains no PO Boxes, GPO Boxes, Locked Bags or Private Bags. Rather than returning a confusing empty list, a query for one returns 200 with an empty suggestions array and a notice, so your form can prompt for a street address or accept the PO Box in a separate field. verify returns the same notice with matched: false and billed: false — a query the dataset cannot answer is never charged.

{ "suggestions": [], "notice": {
  "code": "postal_address_unsupported",
  "kind": "PO Box",
  "message": "PO Box addresses aren’t in the G-NAF dataset…"
} }

Rate limits & billing

Billing is session-based, the same model as Google Places: send a session token with each autocomplete keystroke and the final retrieve, and the whole session counts as one billable lookup — however many keystrokes it took. Autocomplete on its own is never billed. Retrieve or verify with no session token always bills, so always send one.

Every response carries X-WattleAddr-Quota-Limit and X-WattleAddr-Quota-Remaining. Exhausting a plan’s monthly quota returns 402 quota_exceeded; a per-key burst limit returns 429 rate_limited with a Retry-After header. Error and notice codes are stable and safe to switch on — the full list is in the reference.

Data & privacy

Every request is served from Australian infrastructure — no query or matched address is processed, cached or routed offshore, and your end-users’ input never touches a third-party ad platform such as Google Places.

Autocomplete queries and the addresses they match are recorded in a per-workspace search log for usage, debugging and support. In the console you choose what it keeps:

ModeWhat it stores
full (default)Query and matched-address text, in full, until retention purges it.
hashedEach query as a salted keyed hash; matched-address text is dropped. This is pseudonymisation — we hold the key, so it is not anonymisation.
noneNo query or matched-address text at all — only counts, timing and billing.

Retention is configurable (7–365 days, by plan) and old query text is purged automatically; you can also apply a privacy mode to logs already stored, in one click. See the FAQ and Privacy Policy for detail.

Attribution

WattleAddr is built on the open Geocoded National Address File. The G-NAF licence requires attribution. Display this wherever you surface address data:

Incorporates or developed using G-NAF © Geoscape Australia,
licensed under the Open G-NAF End User Licence Agreement.

Explore every endpoint and try calls live in the interactive reference. Questions? hello@wattleaddr.com.au