Skip to content

Docs

Documentation

One API for Australian addresses. Everything is reachable in two clicks. Start with one request, then follow the reference in the rail’s order.

Every endpoint has a copyable request and the shape of its response. The same reference is available as OpenAPI 3.1, and a test fails the build when the document and the running routes disagree.

First sixty seconds

  1. Get a free key

    Sign up for a free key, verify your email and copy your server key. Replace YOUR_KEY in the request with that key.

  2. Send one request

    Send your key in the X-API-Key header.

    curl "https://yepthere.au/v1/addresses?q=9+george+st+syd" -H "X-API-Key: YOUR_KEY"

    For Claude, use the MCP command. For Cursor, use the same endpoint and header in AI assistant setup.

    The free plan includes up to 500 MCP lookups a month. Paid plans use their full allowance. Upgrade your plan.

  3. Read the chosen result’s uprn

    In results[0], uprn is the stable address id, line1 is the street address and line2 is the building name, or null. Keep the chosen result’s uprn for later lookups. This abbreviated example keeps the response’s field names:

    {
      "ok": true,
      "results": [
        {
          "uprn": "GANSW718028803",
          "line1": "9 George Street",
          "line2": null,
          "suburb": "Sydney",
          "state": "NSW",
          "postcode": "2000",
          "latitude": -33.86580248,
          "longitude": 151.20700223,
          "boundaries": {
            "edition": "ASGS Edition 3 (2021)",
            "sa2": {
              "code": "117031644",
              "name": "Sydney (North) - Millers Point"
            },
            "lga": {
              "code": "17200",
              "name": "Sydney"
            },
            "mmm": {
              "category": 1,
              "name": "Metropolitan"
            }
          }
        }
      ]
    }

What to do when it fails

401: check that you replaced YOUR_KEY with your current key and sent the key header. 403: check the browser key’s allowed website and lookup-only rule, or the server key’s plan scope. 429: wait the number of seconds in Retry-After. A monthly quota error means waiting for the reset or changing plan. Find the exact error below.

Find your way

Endpoints

Copy a request and see the response for every endpoint.

The address record

Understand the fields returned for an Australian address.

Boundaries

Find the statistical, electoral and local government areas for an address.

Keys and limits

Choose a key and check its scopes, allowances and rate limits.

Errors

Find the exact error message and what to do next.

Data and changes

Check the loaded release, attribution and what changed.

Integrations

Connect your platform or use the JavaScript and Python clients.

The widget

Add address autocomplete to a form on your website.

AI assistants

Connect Claude or Cursor through MCP.

Base https://yepthere.au/v1. JSON. GDA2020.

Endpoints

Address lookups return the same record shape. GET lookup responses carry ETag and Cache-Control headers. Conditional requests compare weak validators too; they still run the lookup, but a 304 response consumes no monthly allowance but does consume burst capacity. Browser keys allow GET and HEAD lookups only. Examples use sample records.

For JavaScript, use Node 22 ESM. For Python, run with PYTHONPATH=sdk/python. Copy the vendored clients from Integrations to the named paths and keep their MIT licence. Both clients read SESSIONAL_ADDRESSES_KEY in these samples. Both clients provide boundaries(layer, code) and jobs.download(id). Downloads require a jobs-scoped account key and follow a five-minute storage redirect without forwarding credentials. Python parse() includes response.parsed. Raw HTTP examples are also shown for jobs and health checks. Display the G-NAF attribution wherever you publish results.

GET/v1/addresses?q=<text>&limit=8

Autocomplete. Word-level AND match on at least three characters. Returns eight by default, up to twenty.

curl "https://yepthere.au/v1/addresses?q=9+George+Street+Sydney&limit=5" \
  -H "x-api-key: $SESSIONAL_ADDRESSES_KEY"
Response shape
{
  "ok": true,
  "release": "AUG 2026 - Geoscape G-NAF - GDA2020",
  "results": [
    {
      "uprn": "GANSW718028803",
      "line1": "9 George Street",
      "line2": null,
      "suburb": "Sydney",
      "state": "NSW",
      "postcode": "2000",
      "latitude": -33.86580248,
      "longitude": 151.20700223,
      "boundaries": {
        "edition": "ASGS Edition 3 (2021)",
        "sa1": "11703164421",
        "sa2": {
          "code": "117031644",
          "name": "Sydney (North) - Millers Point"
        },
        "sa3": {
          "code": "11703",
          "name": "Sydney Inner City"
        },
        "sa4": {
          "code": "117",
          "name": "Sydney - City and Inner South"
        },
        "gccsa": {
          "code": "1GSYD",
          "name": "Greater Sydney"
        },
        "remoteness": {
          "code": "10",
          "name": "Major Cities of Australia"
        },
        "lga": {
          "code": "17200",
          "name": "Sydney"
        },
        "electorate": {
          "federal": {
            "code": "141",
            "name": "Sydney"
          },
          "state": {
            "code": "10078",
            "name": "Sydney"
          }
        },
        "postalArea": "2000",
        "suburb": {
          "code": "13730",
          "name": "Sydney"
        },
        "mmm": {
          "category": 1,
          "name": "Metropolitan"
        }
      }
    }
  ]
}

GET/v1/addresses?postcode=2000&limit=100

Every address at a postcode. Default 100, maximum 500.

curl "https://yepthere.au/v1/addresses?postcode=2000&limit=500" \
  -H "x-api-key: $SESSIONAL_ADDRESSES_KEY"
Response shape
{
  "ok": true,
  "release": "AUG 2026 - Geoscape G-NAF - GDA2020",
  "results": [
    {
      "uprn": "GANSW718028803",
      "line1": "9 George Street",
      "line2": null,
      "suburb": "Sydney",
      "state": "NSW",
      "postcode": "2000",
      "latitude": -33.86580248,
      "longitude": 151.20700223,
      "boundaries": {
        "edition": "ASGS Edition 3 (2021)",
        "sa1": "11703164421",
        "sa2": {
          "code": "117031644",
          "name": "Sydney (North) - Millers Point"
        },
        "sa3": {
          "code": "11703",
          "name": "Sydney Inner City"
        },
        "sa4": {
          "code": "117",
          "name": "Sydney - City and Inner South"
        },
        "gccsa": {
          "code": "1GSYD",
          "name": "Greater Sydney"
        },
        "remoteness": {
          "code": "10",
          "name": "Major Cities of Australia"
        },
        "lga": {
          "code": "17200",
          "name": "Sydney"
        },
        "electorate": {
          "federal": {
            "code": "141",
            "name": "Sydney"
          },
          "state": {
            "code": "10078",
            "name": "Sydney"
          }
        },
        "postalArea": "2000",
        "suburb": {
          "code": "13730",
          "name": "Sydney"
        },
        "mmm": {
          "category": 1,
          "name": "Metropolitan"
        }
      }
    }
  ]
}

GET/v1/addresses/:id

Resolve a stored G-NAF address ID back to the full record. Zero or one result.

curl "https://yepthere.au/v1/addresses/GANSW718028803" \
  -H "x-api-key: $SESSIONAL_ADDRESSES_KEY"
Response shape
{
  "ok": true,
  "release": "AUG 2026 - Geoscape G-NAF - GDA2020",
  "results": [
    {
      "uprn": "GANSW718028803",
      "line1": "9 George Street",
      "line2": null,
      "suburb": "Sydney",
      "state": "NSW",
      "postcode": "2000",
      "latitude": -33.86580248,
      "longitude": 151.20700223,
      "boundaries": {
        "edition": "ASGS Edition 3 (2021)",
        "sa1": "11703164421",
        "sa2": {
          "code": "117031644",
          "name": "Sydney (North) - Millers Point"
        },
        "sa3": {
          "code": "11703",
          "name": "Sydney Inner City"
        },
        "sa4": {
          "code": "117",
          "name": "Sydney - City and Inner South"
        },
        "gccsa": {
          "code": "1GSYD",
          "name": "Greater Sydney"
        },
        "remoteness": {
          "code": "10",
          "name": "Major Cities of Australia"
        },
        "lga": {
          "code": "17200",
          "name": "Sydney"
        },
        "electorate": {
          "federal": {
            "code": "141",
            "name": "Sydney"
          },
          "state": {
            "code": "10078",
            "name": "Sydney"
          }
        },
        "postalArea": "2000",
        "suburb": {
          "code": "13730",
          "name": "Sydney"
        },
        "mmm": {
          "category": 1,
          "name": "Metropolitan"
        }
      }
    }
  ]
}

GET/v1/nearest?lat=&lng=&limit=5

Reverse geocode. The closest addresses to a point, with distance in metres. Maximum 20.

curl "https://yepthere.au/v1/nearest?lat=-33.8658&lng=151.2070" \
  -H "x-api-key: $SESSIONAL_ADDRESSES_KEY"
Response shape
{
  "ok": true,
  "release": "AUG 2026 - Geoscape G-NAF - GDA2020",
  "results": [
    {
      "uprn": "GANSW718028803",
      "line1": "9 George Street",
      "line2": null,
      "suburb": "Sydney",
      "state": "NSW",
      "postcode": "2000",
      "latitude": -33.86580248,
      "longitude": 151.20700223,
      "distanceMetres": 12.4
    }
  ]
}

GET/v1/postcodes/:postcode

The postcode itself: suburbs it covers, state, and a centroid. One aggregate per state. suburbRanking lists name, state and addressCount per suburb, most addresses first; suburbs remains a string array. Unknown postcodes return 404 with postcode-not-found.

curl "https://yepthere.au/v1/postcodes/3000" \
  -H "x-api-key: $SESSIONAL_ADDRESSES_KEY"
Response shape
{
  "ok": true,
  "release": "AUG 2026 - Geoscape G-NAF - GDA2020",
  "results": [
    {
      "postcode": "3000",
      "state": "VIC",
      "suburbs": [
        "Melbourne"
      ],
      "addressCount": 100,
      "latitude": -37.81,
      "longitude": 144.96
    }
  ]
}

GET/v1/postcodes?q=<prefix-or-suburb>&limit=8

Postcode and suburb autocomplete. Supply a postcode prefix of one to four digits or a suburb name. Returns eight by default, up to twenty.

curl "https://yepthere.au/v1/postcodes?q=melbourne" \
  -H "x-api-key: $SESSIONAL_ADDRESSES_KEY"
Response shape
{
  "ok": true,
  "release": "AUG 2026 - Geoscape G-NAF - GDA2020",
  "results": [
    {
      "postcode": "3000",
      "state": "VIC",
      "suburbs": [
        "Melbourne"
      ],
      "addressCount": 100,
      "latitude": -37.81,
      "longitude": 144.96
    }
  ]
}

GET/v1/boundaries/:layer/:code

A boundary by layer (mmm, remoteness, lga, sa2, sa3, sa4, federal, state, poa, sal) and code: its name and the postcodes it touches with address counts. Returns 404 boundary-not-found for unknown codes or when no boundary set is loaded.

curl "https://yepthere.au/v1/boundaries/lga/17200" \
  -H "x-api-key: $SESSIONAL_ADDRESSES_KEY"
Response shape
{
  "ok": true,
  "release": "AUG 2026 - Geoscape G-NAF - GDA2020",
  "results": [
    {
      "layer": "lga",
      "code": "17200",
      "name": "Sydney",
      "postcodes": [
        {
          "postcode": "2000",
          "state": "NSW",
          "addresses": 100
        }
      ]
    }
  ]
}

POST/v1/parse

Messy address text in, structured components and ranked G-NAF matches out, with a confidence and what matched. Body { "q": "unit 3/42 wallaby way syd 2000", "limit": 3 }. PO boxes are recognised and never matched. When the rule-based parser is unsure the text is passed to a language model. The privacy page explains what is sent. Needs the parse scope.

curl -X POST "https://yepthere.au/v1/parse" \
  -H "x-api-key: $SESSIONAL_ADDRESSES_KEY" \
  -H "content-type: application/json" \
  -d '{"q":"unit 3/42 wallaby way syd 2000","limit":3}'
Response shape
{
  "ok": true,
  "release": "AUG 2026 - Geoscape G-NAF - GDA2020",
  "parsed": {
    "unit": "3",
    "number": "42",
    "numberTo": null,
    "street": "WALLABY",
    "streetType": "WAY",
    "suburb": "SYDNEY",
    "state": "NSW",
    "postcode": "2000",
    "kind": "street",
    "method": "rules",
    "confidence": 0.94
  },
  "results": [
    {
      "uprn": "GANSW718028803",
      "line1": "9 George Street",
      "line2": null,
      "suburb": "Sydney",
      "state": "NSW",
      "postcode": "2000",
      "latitude": -33.86580248,
      "longitude": 151.20700223,
      "confidence": 0.94,
      "matchedOn": [
        "number",
        "street",
        "suburb"
      ]
    }
  ]
}

POST/v1/addresses/bulk

Up to 100 queries in one request. Each counts as one lookup. Results come back in the order sent. Each query is an object with q and an optional limit, default 1, maximum 5.

curl -X POST "https://yepthere.au/v1/addresses/bulk" \
  -H "x-api-key: $SESSIONAL_ADDRESSES_KEY" \
  -H "content-type: application/json" \
  -d '{"queries":[{"q":"1 george st sydney"},{"q":"42 wallaby way"}]}'
Response shape
{
  "ok": true,
  "release": "AUG 2026 - Geoscape G-NAF - GDA2020",
  "results": [
    {
      "q": "1 george st sydney",
      "results": [
        {
          "uprn": "GANSW718028803",
          "line1": "9 George Street",
          "line2": null,
          "suburb": "Sydney",
          "state": "NSW",
          "postcode": "2000",
          "latitude": -33.86580248,
          "longitude": 151.20700223
        }
      ]
    },
    {
      "q": "42 wallaby way",
      "results": []
    }
  ]
}

POST/v1/jobs

Submit a CSV of addresses to match and geocode as a job. Send the file as the body with Content-Type text/csv, up to 10,485,760 bytes and 50,000 rows. Headers x-job-column and x-job-filename set the address column and filename. Read job.id from the response. estimatedSecondsRemaining includes work scheduled ahead; estimatedReadyAt is an ISO 8601 UTC ready time. Both are estimates and tighten as processing advances. Every successfully processed row counts one job row; error rows cost nothing. Needs the jobs scope.

curl -X POST "https://yepthere.au/v1/jobs" \
  -H "x-api-key: $SESSIONAL_ADDRESSES_KEY" \
  -H "content-type: text/csv" -H "x-job-column: address" \
  --data-binary @addresses.csv
Response shape
{
  "ok": true,
  "job": {
    "id": "job_example",
    "status": "queued",
    "rowCount": 1200
  }
}

GET/v1/jobs/:id

Job state, estimatedSecondsRemaining, estimatedReadyAt (ISO 8601 UTC), counts by confidence band, errorRows for failed row lookups, and an authenticated download URL once the job is done. Send your account key to GET /v1/jobs/:id/download; it redirects to storage for five minutes (404 if unknown or expired, 409 if not done).

curl "https://yepthere.au/v1/jobs/job_example" \
  -H "x-api-key: $SESSIONAL_ADDRESSES_KEY"
Response shape
{
  "ok": true,
  "job": {
    "id": "job_example",
    "filename": "addresses.csv",
    "column": "address",
    "status": "done",
    "estimatedSecondsRemaining": 0,
    "estimatedReadyAt": "2026-10-18T00:00:00.000Z",
    "rowCount": 1200,
    "matchedHigh": 1104,
    "matchedLow": 71,
    "unmatched": 25,
    "errorRows": 0,
    "downloadUrl": "https://yepthere.au/v1/jobs/job_example/download",
    "expiresAt": "2026-10-25T00:00:00.000Z"
  }
}

GET/v1/jobs/:id/download

Download completed CSV results with the owning account key and jobs scope. Returns a 302 redirect to a five-minute storage URL, 404 for unknown or expired jobs, and 409 until done. Do not forward credentials to storage.

curl --location "https://yepthere.au/v1/jobs/job_example/download" \
  -H "Authorization: Bearer $SESSIONAL_ADDRESSES_KEY"
Response shape
{
  "status": 302,
  "Location": "https://storage.example/results.csv?X-Amz-Expires=300"
}

GET/v1/jobs

List the last 50 jobs for your account. Needs the jobs scope.

curl "https://yepthere.au/v1/jobs" \
  -H "x-api-key: $SESSIONAL_ADDRESSES_KEY"
Response shape
{
  "ok": true,
  "jobs": [
    {
      "id": "job_example",
      "filename": "addresses.csv",
      "column": "address",
      "status": "done",
      "estimatedSecondsRemaining": 0,
      "estimatedReadyAt": "2026-10-18T00:00:00.000Z",
      "rowCount": 1200,
      "matchedHigh": 1104,
      "matchedLow": 71,
      "unmatched": 25,
      "errorRows": 0,
      "downloadUrl": "https://yepthere.au/v1/jobs/job_example/download",
      "expiresAt": "2026-10-25T00:00:00.000Z"
    }
  ]
}

GET/health

Cheap process liveness check. It does not query PostgreSQL. No key required.

curl "https://yepthere.au/health"
Response shape
{
  "ok": true
}

GET/ready

Readiness, row count, release ID, release name and load timestamp. Returns 503 until loaded or when the database is unavailable. No key required.

curl "https://yepthere.au/ready"
Response shape
{
  "ok": true,
  "ready": true,
  "rowCount": 16091511,
  "releaseId": "b023544a-5836-4d43-b6d8-da2f73e8d2bf:2026-08-17T03:24:56.565849",
  "releaseName": "AUG 2026 - Geoscape G-NAF - GDA2020",
  "loadedAt": "2026-10-25T12:11:35.160Z"
}

The address record

Fields are stable across releases. Coordinates use GDA2020 decimal degrees. Postcodes are strings so leading zeros are retained. Building names, coordinates and boundary fields can be null.

{
  "uprn": "GANSW718028803",
  "line1": "9 George Street",
  "line2": null,
  "suburb": "Sydney",
  "state": "NSW",
  "postcode": "2000",
  "latitude": -33.86580248,
  "longitude": 151.20700223,
  "boundaries": {
    "edition": "ASGS Edition 3 (2021)",
    "sa1": "11703164421",
    "sa2": {
      "code": "117031644",
      "name": "Sydney (North) - Millers Point"
    },
    "sa3": {
      "code": "11703",
      "name": "Sydney Inner City"
    },
    "sa4": {
      "code": "117",
      "name": "Sydney - City and Inner South"
    },
    "gccsa": {
      "code": "1GSYD",
      "name": "Greater Sydney"
    },
    "remoteness": {
      "code": "10",
      "name": "Major Cities of Australia"
    },
    "lga": {
      "code": "17200",
      "name": "Sydney"
    },
    "electorate": {
      "federal": {
        "code": "141",
        "name": "Sydney"
      },
      "state": {
        "code": "10078",
        "name": "Sydney"
      }
    },
    "postalArea": "2000",
    "suburb": {
      "code": "13730",
      "name": "Sydney"
    },
    "mmm": {
      "category": 1,
      "name": "Metropolitan"
    }
  }
}
uprn
G-NAF address detail PID. Stable across releases.
line1
Number and street, with the unit or flat where there is one.
line2
Building or site name when G-NAF carries one, otherwise null.
suburb
Locality name as gazetted.
state
NSW, VIC, QLD, SA, WA, TAS, NT, ACT or OT (Other Territories).
postcode
Four digits as a string.
latitude
GDA2020 decimal degrees. Property centroid where G-NAF has one.
longitude
GDA2020 decimal degrees.
boundaries
Present once a boundary set is loaded. Nearest results add distanceMetres. Postcode results contain state aggregates with an addressCount. Bulk results contain each query and its results in request order. Successful lookup envelopes include the release name and boundaries.edition, for example ASGS Edition 4 (2026). Address boundary objects also include edition. A null edition means no recognised ASGS set is loaded. The configured switch selects the next load; responses describe the loaded set, including after rollback.

Boundary layers

Each address is joined using its G-NAF Mesh Block and through the ABS allocation files to these areas. Codes are the official ABS and AEC codes. Use /v1/boundaries/:layer/:code to go the other way, from a boundary to the postcodes it touches.

FieldLayerNotes
sa1Statistical Area 1The smallest ABS unit with published statistics. Code only.
sa2Statistical Area 2The level most reporting uses. Code and name.
sa3Statistical Area 3Code and name.
sa4Statistical Area 4Code and name.
gccsaGreater capital city areaGreater Sydney, Rest of NSW and so on. Code and name.
remotenessRemoteness areaMajor Cities of Australia through to Very Remote Australia, 2021.
lgaLocal government area2025 allocation. Code and name.
electorate.federalFederal electorateCommonwealth Electoral Division, 2025 allocation.
electorate.stateState electorateState Electoral Division, 2025 allocation.
postalAreaPostal areaThe ABS postal area code, which can differ from the delivery postcode.
suburbSuburb or localityABS suburb and locality code and name, 2021.
mmmModified Monash categoryMMM 2023, category 1 for metropolitan through 7 for very remote.

Keys and limits

Your account’s plan sets each key’s allowance and rate, and how many keys you can create. See plan prices.

Server keys

Server keys start with sak_live_. Use them in server code, scripts, CSV jobs and MCP clients. Keep them in environment variables or server secrets. Send x-api-key: $SESSIONAL_ADDRESSES_KEY or Authorization: Bearer $SESSIONAL_ADDRESSES_KEY. Keys are shown once; rotate or revoke them in your account. Health, readiness, status and docs need no key.

Browser keys

For local development, allowed websites may use http://localhost[:port], http://127.0.0.1[:port] or http://[::1][:port]. Other HTTP origins are rejected. Browser keys start with sab_live_. Use them for a widget or autocomplete in a public page. Visitors can see them. They allow lookup-only access through GET and HEAD, even on plans with parse or jobs. They cannot call parse, bulk, jobs or MCP.

List 1 to 10 allowed websites as hostnames or HTTPS origins, without a path, query or fragment. For example, shop.example.com.au and https://shop.example.com.au allow the same hostname. Names are case-insensitive, and ports do not restrict access for hostname and HTTPS entries. A normal entry matches that exact hostname.

*.example.com.au allows one subdomain level, such as shop.example.com.au. It does not allow example.com.au or au.shop.example.com.au. Add the bare domain separately if you need it. Wildcards must use your own domain; shared suffixes such as *.com.au and *.github.io are rejected.

The request must come over HTTPS, except for local development: list http://localhost:3000, http://127.0.0.1:8080 or http://[::1]:3000 exactly as your browser sends it, scheme, host and port, and that origin is allowed over plain HTTP. The service checks Origin first and uses Referer only when Origin is absent. A missing or invalid website is rejected.

Scopes by plan

Server scopes follow your account’s plan, including after a downgrade. Every plan has lookup; a non-zero parse allowance adds parse, and a non-zero CSV allowance adds jobs. Browser keys keep only lookup.

Plan allowances and server key scopes
PlanScopesLookups a monthParses a monthCSV rowsKeysRequests a second
Freesearch, resolve, nearest, postcodes, bulk, parse5,000100015
Supportersearch, resolve, nearest, postcodes, bulk, parse10,0005000210
Prosearch, resolve, nearest, postcodes, bulk, parse, jobs100,00010,000100,000520
Scalesearch, resolve, nearest, postcodes, bulk, parse, jobs500,00050,000500,0002550

Monthly reset and quota emails

Each key’s monthly lookup allowance resets at 00:00 UTC on the first day of each month. Successful parse requests use only the parse allowance, with no lookup charge. Bulk requests count once per query and CSV jobs once per successfully processed row. We send quota emails at 80 per cent and 100 per cent of a key’s monthly lookup allowance.

Burst limits and response headers

The burst limit applies per key. The table shows the plan’s requests a second. Browser keys are capped at 5 requests a second, or the plan’s lower rate. An active throttle can lower either rate. Debounce typing and wait before retrying a 429 response.

HeaderMeaning
X-RateLimit-BurstThe effective burst rate in requests a second, including any active throttle. Internal keys are exempt.
X-RateLimit-LimitThe key's monthly lookup limit.
X-RateLimit-RemainingLookups remaining after a successful response.
X-RateLimit-ResetThe first instant of the next UTC calendar month in ISO 8601 format.
Retry-AfterWhole seconds to wait after burst or monthly quota throttling.

The three monthly headers are sent after a registered key passes authentication, scope, burst and quota checks. They are also present if that request then fails validation. Rejected keys and the trusted system key do not receive these headers. The system key bypasses registered-key quota and burst checks.

The JavaScript and Python clients retry transient failures with bounded exponential backoff and honour capped Retry-After delays; parse and job submission are retried only with an explicit opt-in.

Example after the first lookup on a free server key, during October 2026:

X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 4999
X-RateLimit-Reset: 2026-11-01T00:00:00.000Z
X-RateLimit-Burst: 5

A burst rejection can instead return Retry-After: 1, which means wait at least one second before retrying. A monthly quota rejection gives the seconds until the reset.

Request ids and support

Every response includes X-Request-Id. Please quote that request id when you write to [email protected], so we can find the request.

Errors

REST errors normally contain ok: false, an error code, a human message and empty results. The readiness response and unknown-route response omit results. MCP protocol failures use a JSON-RPC error object with a numeric code and message; tool results carry the underlying API error.

{
  "ok": false,
  "error": "invalid-api-key",
  "message": "A valid API key is required.",
  "results": []
}

The table lists message variants separately. In a message template, ${host} is the request hostname, or an unknown website when it cannot be read; ${index} is the zero-based query index. Other placeholders identify request values or the limits named in the message. MCP tool errors carry the underlying API status shown here, while the MCP HTTP response can still be 200.

StatusCodeExact message or templateWhat to do
429mcp-free-limitThe free plan includes 500 MCP lookups a month.Wait until the next UTC month or upgrade for MCP within your full allowance.
402plan-requiredThis capability requires a paid plan.Upgrade for the requested capability.
401invalid-api-keyA valid API key is required.Send a current key in x-api-key or Authorization: Bearer.
401key-revokedThis API key has been revoked.Create a new key in your account and replace the old one.
403account-suspendedThis account has been suspended.Contact support with the request id.
403insufficient-scopeThis API key does not have the required scope.Choose a plan with the required parse or jobs allowance.
403origin-not-allowedThis browser key is not allowed from ${host}.Add the website hostname to the key’s allowlist. Send Origin, or Referer when Origin is absent.
403ip-not-allowedThis key is not allowed from ${address}.Add the caller address or CIDR range to the server key’s IP allowlist.
403scope-deniedThis browser key only allows lookups.Use GET or HEAD lookups, or move this call to a server with a server key.
429rate-limitedToo many requests. Please try again later.Wait Retry-After seconds, then reduce the request rate.
429quota-exceededThis API key has exhausted its monthly quota.Wait until the monthly reset or change your plan. Respect Retry-After.
400invalid-querySupply exactly one of q or postcodeCorrect the named query parameter and send it once.
400invalid-queryq must contain at least 3 charactersCorrect the named query parameter and send it once.
400invalid-queryInclude a street or suburb name; single digits need an alphabetic word of at least 3 characters.Correct the named query parameter and send it once.
400invalid-queryq must contain no more than 200 charactersCorrect the named query parameter and send it once.
400invalid-querypostcode must contain exactly 4 digitsCorrect the named query parameter and send it once.
400invalid-querylimit must be a positive whole numberCorrect the named query parameter and send it once.
400invalid-queryq is requiredCorrect the named query parameter and send it once.
400invalid-queryq must contain at least 1 characterCorrect the named query parameter and send it once.
400invalid-queryq must contain no more than 100 charactersCorrect the named query parameter and send it once.
400invalid-querypostcode prefix must contain between 1 and 4 digitsCorrect the named query parameter and send it once.
400invalid-queryq must be a postcode prefix or suburb nameCorrect the named query parameter and send it once.
400invalid-queryq must be supplied onceCorrect the named query parameter and send it once.
400invalid-querypostcode must be supplied onceCorrect the named query parameter and send it once.
400invalid-querylimit must be supplied onceCorrect the named query parameter and send it once.
400invalid-querylat must be supplied onceCorrect the named query parameter and send it once.
400invalid-querylng must be supplied onceCorrect the named query parameter and send it once.
400invalid-querylat is requiredCorrect the named query parameter and send it once.
400invalid-querylng is requiredCorrect the named query parameter and send it once.
400invalid-querylat must be a number between -90 and 90Correct the named query parameter and send it once.
400invalid-querylng must be a number between -180 and 180Correct the named query parameter and send it once.
414uri-too-longid must contain no more than 100 charactersUse the uprn from an address record.
400invalid-queryqueries[${index}].q must not be emptySupply address text after removing control characters.
400invalid-idid must contain between 1 and 100 charactersUse the uprn from an address record.
400invalid-postcodepostcode must contain exactly 4 digitsSend a four-digit postcode as text, including leading zeros.
400invalid-postcodepostcode must be supplied onceSend a four-digit postcode as text, including leading zeros.
400invalid-boundarylayer must be mmm, remoteness, lga, sa2, sa3, sa4, federal, state, poa or salUse a listed layer and its official code.
400invalid-boundaryMMM category must be between 1 and 7Use a listed layer and its official code.
400invalid-boundarycode must contain 1 to 32 letters, digits, underscores or hyphensUse a listed layer and its official code.
400invalid-boundarylayer must be supplied onceUse a listed layer and its official code.
400invalid-boundarycode must be supplied onceUse a listed layer and its official code.
400invalid-bodybody must be an objectCorrect the JSON body. The index identifies the query, starting at zero.
400invalid-bodyqueries must be an arrayCorrect the JSON body. The index identifies the query, starting at zero.
400invalid-bodyqueries must contain between 1 and 100 itemsCorrect the JSON body. The index identifies the query, starting at zero.
400invalid-bodyqueries[${index}] must be an objectCorrect the JSON body. The index identifies the query, starting at zero.
400invalid-bodyqueries[${index}].q must be supplied onceCorrect the JSON body. The index identifies the query, starting at zero.
400invalid-bodyqueries[${index}].q is requiredCorrect the JSON body. The index identifies the query, starting at zero.
400invalid-bodyqueries[${index}].q must contain at least 3 charactersCorrect the JSON body. The index identifies the query, starting at zero.
400invalid-bodyqueries[${index}].q must contain no more than 200 charactersCorrect the JSON body. The index identifies the query, starting at zero.
400invalid-bodylimit must be supplied onceCorrect the JSON body. The index identifies the query, starting at zero.
400invalid-bodylimit must be a positive whole numberCorrect the JSON body. The index identifies the query, starting at zero.
400invalid-bodyq must contain between 3 and 300 charactersCorrect the JSON body. The index identifies the query, starting at zero.
400invalid-bodylimit must be a whole number between 1 and 20Correct the JSON body. The index identifies the query, starting at zero.
400invalid-bodyThe request could not be processed.Correct the JSON body. The index identifies the query, starting at zero.
413invalid-bodybody must contain no more than 4096 bytesShorten the parse body.
415unsupported-media-typeSend application/json.Send parse and bulk requests with Content-Type application/json.
404postcode-not-foundPostcode was not found.Check the postcode or search by suburb.
404boundary-not-foundBoundary was not found.Check the layer and code, and whether boundary data is loaded.
503address-lookup-unavailableAddress data has not been loaded.Check /ready and retry after the data is loaded.
500address-lookup-errorAddress lookup failed.Retry later. Contact support with the request id if it continues.
500address-lookup-errorNearest address lookup failed.Retry later. Contact support with the request id if it continues.
500address-lookup-errorPostcode lookup failed.Retry later. Contact support with the request id if it continues.
500address-lookup-errorBoundary lookup failed.Retry later. Contact support with the request id if it continues.
500parse-errorAddress parsing failed.Retry later. Contact support with the request id if it continues.
503jobs-unavailableAddress jobs are unavailable.Check service status. Check your recent jobs before resubmitting.
503jobs-unavailableThe address job could not be submitted.Check service status. Check your recent jobs before resubmitting.
415invalid-content-typeSend a CSV file with Content-Type text/csv.Upload raw CSV with the text/csv header.
403account-requiredAn account API key is required for address jobs.Use a server key from an account with jobs scope.
400invalid-job-headersSupply a column and filename within the allowed lengths.Use 1 to 256 characters for x-job-column and 1 to 255 for x-job-filename, without control characters in the filename.
404job-not-foundThe address job was not found.Use a job id belonging to this account.
400invalid-csvA quote must start a CSV field.Correct the CSV and the x-job-column header, then upload it again.
400invalid-csvUnexpected text after a quoted CSV field.Correct the CSV and the x-job-column header, then upload it again.
400invalid-csvA quoted CSV field was not closed.Correct the CSV and the x-job-column header, then upload it again.
400invalid-csvSend a UTF-8 CSV file.Correct the CSV and the x-job-column header, then upload it again.
400invalid-csvThe CSV file is empty.Correct the CSV and the x-job-column header, then upload it again.
400invalid-csvThe address column was not found.Correct the CSV and the x-job-column header, then upload it again.
400invalid-csvThe address column must have a unique name.Correct the CSV and the x-job-column header, then upload it again.
400invalid-csvCSV rows must have the same number of columns.Correct the CSV and the x-job-column header, then upload it again.
400invalid-csvThe CSV file must contain at least one address row.Correct the CSV and the x-job-column header, then upload it again.
413csv-too-largeCSV files must be no larger than 10,485,760 bytes.Split the CSV into smaller files.
413csv-too-largeCSV files must contain no more than 50,000 rows.Split the CSV into smaller files.
503database-unavailableNo message field; /ready returns ok: false and ready: false.Check service status and retry later.
500internal-errorSomething went wrong.Contact support with the request id if retrying does not help.
404not-foundRoute not found.Check the HTTP method and endpoint path.
4xxbad-request${error.message}Correct the request described by the message. This is the fallback code when an error has no code.
413FST_ERR_CTP_BODY_TOO_LARGERequest body is too largeReduce the body: bulk accepts 64 KiB and CSV accepts 10,485,760 bytes.
415FST_ERR_CTP_INVALID_MEDIA_TYPEUnsupported Media TypeSend the content type required by the endpoint.
400FST_ERR_CTP_EMPTY_JSON_BODYBody cannot be empty when content-type is set to 'application/json'Send a JSON object.
400FST_ERR_CTP_INVALID_JSON_BODYBody is not valid JSON but content-type is set to 'application/json'Fix the JSON syntax.
400FST_ERR_CTP_INVALID_CONTENT_LENGTHRequest body size did not match Content-LengthLet your HTTP client set Content-Length.
415-32000Content-Type must be application/json.Send MCP requests as application/json.
406-32000Not Acceptable: Client must accept both application/json and text/event-streamInclude application/json and text/event-stream in the MCP Accept header.
400-32000Bad Request: Unsupported protocol version: ${protocolVersion} (supported versions: ${SUPPORTED_PROTOCOL_VERSIONS.join(', ')})Use a supported MCP protocol version. The message lists the accepted versions.
405-32000Method not allowed. This MCP server is stateless; use POST.Use POST /mcp.
400-32700Invalid JSON body.Fix the JSON syntax of the MCP request.
400-32700Parse error: Invalid JSON-RPC messageSend a valid JSON-RPC 2.0 request. Inspect any error data for details.
400-32700Parse errorSend a valid JSON-RPC 2.0 request. Inspect any error data for details.
400-32600Invalid Request: Batch must not exceed ${MAX_BATCH_SIZE} messagesSplit the batch and send initialization on its own.
400-32600Invalid Request: Only one initialization request is allowedSplit the batch and send initialization on its own.
200-32601Method not foundUse an MCP method advertised by this server.
200-32602MCP error -32602: Resource ${uri} not foundList the available resources or prompts and check the supplied arguments.
200-32602MCP error -32602: Prompt ${request.params.name} not foundList the available resources or prompts and check the supplied arguments.
200-32602MCP error -32602: Invalid arguments for prompt ${request.params.name}: ${errorMessage}List the available resources or prompts and check the supplied arguments.
200-32602MCP error -32602: Tool ${request.params.name} not foundList the available tools and use an advertised name.
200-32602MCP error -32602: Input validation error: Invalid arguments for tool ${toolName}: ${errorMessage}Check the tool input against its advertised schema.
200-32603The OpenAPI document is unavailable.Retry reading the MCP openapi resource later.
413-32603The request body exceeds 1 MB.Shorten the MCP request body.
429 / 500-32603The MCP request could not be processed.Respect Retry-After when present. Contact support with the request id if it continues.
502api-unavailableThe address API could not be reached.Retry the MCP tool later.
502invalid-api-responseThe address API returned an unexpected response.Contact support with the request id.
4xx/5xxmcp-usage-unavailableMCP usage is unavailable. Try again shortly.Check the request and service status.
400invalid-queryq must not be emptyCorrect the named query parameter and send it once.
429quota-exceededThis API key has insufficient monthly job rows for this file.Wait until the monthly reset or change your plan. Respect Retry-After.
409job-not-readyThe address job is not ready to download.Check the request and service status.
414uri-too-longThe request path is too long.Use the uprn from an address record.

Data and changes

Reloaded each quarter. Release metadata below is read from the repository through the readiness check for this page request. What changed.

ReleaseLoadedAddresses
AUG 2026 - Geoscape G-NAF - GDA20202026-10-25T12:11:35.160Z16091511

G-NAF is published by Geoscape Australia as open data through data.gov.au under the G-NAF End User Licence Agreement. Boundaries come from the Australian Bureau of Statistics ASGS Edition 3 or Edition 4 allocation files (CC BY 4.0), as identified by boundaries.edition, and the Modified Monash Model 2023 by Mesh Block from the Department of Health and Aged Care (CC BY 2.5 AU). Read the usage policy for attribution and the mail-use condition.

What changed

The new plan ladder includes Supporter. Plans set per-key rates and scopes. Browser keys restrict lookups to allowed websites. The MCP server, address widget and integration guides help you connect your application. Every response now includes a request id for support.