Docs

API reference

Every endpoint with 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.

Endpoints

Address lookups return the same record shape. GET responses carry an ETag and a Cache-Control header, and CORS allows GET and POST from a browser. Examples use the public service and sample records.

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

Autocomplete. Word-level AND match on at least three characters. Default 8 results, maximum 20.

curl "https://addresses.sessional.au/v1/addresses?q=collins+st+melb" \
  -H "x-api-key: $SESSIONAL_ADDRESS_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": {
        "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://addresses.sessional.au/v1/addresses?postcode=2000&limit=500" \
  -H "x-api-key: $SESSIONAL_ADDRESS_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": {
        "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://addresses.sessional.au/v1/addresses/GANSW718028803" \
  -H "x-api-key: $SESSIONAL_ADDRESS_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": {
        "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://addresses.sessional.au/v1/nearest?lat=-33.8658&lng=151.2070" \
  -H "x-api-key: $SESSIONAL_ADDRESS_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. Unknown postcodes return 404 with postcode-not-found.

curl "https://addresses.sessional.au/v1/postcodes/3000" \
  -H "x-api-key: $SESSIONAL_ADDRESS_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. Default 8 results, maximum 20.

curl "https://addresses.sessional.au/v1/postcodes?q=melbourne" \
  -H "x-api-key: $SESSIONAL_ADDRESS_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. Available once a boundary set is loaded.

curl "https://addresses.sessional.au/v1/boundaries/lga/17200" \
  -H "x-api-key: $SESSIONAL_ADDRESS_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://addresses.sessional.au/v1/parse" \
  -H "x-api-key: $SESSIONAL_ADDRESS_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",
  "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://addresses.sessional.au/v1/addresses/bulk" \
  -H "x-api-key: $SESSIONAL_ADDRESS_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 MiB and 50,000 rows. Header x-job-column names the address column. Every processed row counts one lookup. Needs the jobs scope.

curl -X POST "https://addresses.sessional.au/v1/jobs" \
  -H "x-api-key: $SESSIONAL_ADDRESS_KEY" \
  -H "content-type: text/csv" -H "x-job-column: address" \
  --data-binary @addresses.csv
Response shape
{
  "ok": true,
  "release": "AUG 2026 - Geoscape G-NAF - GDA2020",
  "results": [
    {
      "id": "job_example",
      "state": "done",
      "rows": 1200,
      "matched": {
        "high": 1104,
        "medium": 71,
        "low": 25
      },
      "downloadUrl": "https://example.invalid/results.csv",
      "expiresAt": "2026-09-13T00:00:00.000Z"
    }
  ]
}

GET/v1/jobs/:id

Job state, counts by confidence band, and a download link that lasts 24 hours once the job is done. GET /v1/jobs lists the last 50 jobs for the account.

curl "https://addresses.sessional.au/v1/jobs/job_example" \
  -H "x-api-key: $SESSIONAL_ADDRESS_KEY"
Response shape
{
  "ok": true,
  "release": "AUG 2026 - Geoscape G-NAF - GDA2020",
  "results": [
    {
      "id": "job_example",
      "state": "done",
      "rows": 1200,
      "matched": {
        "high": 1104,
        "medium": 71,
        "low": 25
      },
      "downloadUrl": "https://example.invalid/results.csv",
      "expiresAt": "2026-09-13T00:00:00.000Z"
    }
  ]
}

GET/health

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

curl "https://addresses.sessional.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://addresses.sessional.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-09-11T23:03:30.367Z"
}

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": {
    "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 or ACT.
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.

Boundary layers

Each address is joined to its 2021 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

The quota is per key per UTC calendar month and depends on the account's plan, from 10,000 lookups on the free key. Every key has a burst limit of 10 requests a second. Bulk requests count once per query inside them, and CSV jobs count once per processed row. See the plans.

Send x-api-key: $SESSIONAL_ADDRESS_KEY or Authorization: Bearer $SESSIONAL_ADDRESS_KEY on every lookup. Keys begin with sak_live_, are shown once and have the lookup scope by default. The parse and jobs scopes are granted per key. Health, status and docs need no key.

HeaderMeaning
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.

Errors

Every error is JSON with a stable error code and a human message. Results are always an array, empty on failure.

{
  "ok": false,
  "error": "invalid-api-key",
  "message": "A valid API key is required.",
  "results": []
}
StatusErrorMessage
401invalid-api-keyA valid API key is required.
403key-revokedThis API key has been revoked.
403account-suspendedThis account has been suspended.
403insufficient-scopeThis API key does not have the required scope.
429rate-limitedToo many requests. Please try again later.
429quota-exceededThis API key has exhausted its monthly quota.

Lookup validation errors return 400 with invalid-query, invalid-id, invalid-postcode or invalid-body. Missing address data returns 503 with address-lookup-unavailable, and CSV jobs return 503 with jobs-unavailable while job storage is not configured. A failed lookup returns 500 with address-lookup-error.

Data

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

ReleaseLoadedAddresses
AUG 2026 - Geoscape G-NAF - GDA20202026-09-11T23:03:30.367Z16091511

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 allocation files (CC BY 4.0) 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.