@bradleyhodges/addresskit 2.2.3 → 2.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +430 -156
  2. package/api/swagger.yaml +353 -0
  3. package/dist/cli.js +757 -2295
  4. package/package.json +17 -12
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  <br />
4
4
 
5
- [![GitHub license](https://img.shields.io/github/license/bradleyhodges/addresskit)](https://github.com/bradleyhodges/addresskit/blob/master/LICENSE) [![npm](https://img.shields.io/npm/v/@bradleyhodges/addresskit)](https://www.npmjs.com/package/@bradleyhodges/addresskit) [![npm downloads](https://img.shields.io/npm/dm/@bradleyhodges/addresskit)](https://www.npmjs.com/package/@bradleyhodges/addresskit) [![Docker Image Version (latest by date)](https://img.shields.io/docker/v/@bradleyhodges/addresskit?label=image%20version)](https://hub.docker.com/r/@bradleyhodges/addresskit) [![Docker Pulls](https://img.shields.io/docker/pulls/@bradleyhodges/addresskit)](https://hub.docker.com/r/@bradleyhodges/addresskit)
5
+ [![GitHub license](https://img.shields.io/github/license/bradleyhodges/addresskit)](https://github.com/bradleyhodges/addresskit/blob/master/LICENSE) [![npm](https://img.shields.io/npm/v/@bradleyhodges/addresskit)](https://www.npmjs.com/package/@bradleyhodges/addresskit) [![npm downloads](https://img.shields.io/npm/dm/@bradleyhodges/addresskit)](https://www.npmjs.com/package/@bradleyhodges/addresskit) [![Docker Image Version (latest by date)](https://img.shields.io/docker/v/bradleyhodges/addresskit?label=image%20version)](https://hub.docker.com/r/bradleyhodges/addresskit) [![Docker Pulls](https://img.shields.io/docker/pulls/bradleyhodges/addresskit)](https://hub.docker.com/r/bradleyhodges/addresskit)
6
6
 
7
7
  [![GitHub issues](https://img.shields.io/github/issues/bradleyhodges/addresskit)](https://github.com/bradleyhodges/addresskit/issues) [![GitHub pull requests](https://img.shields.io/github/issues-pr/bradleyhodges/addresskit)](https://github.com/bradleyhodges/addresskit/pulls) [![Libraries.io dependency status for latest release](https://img.shields.io/librariesio/release/npm/@bradleyhodges/addresskit)](https://libraries.io/npm/@bradleyhodges%2Faddresskit)
8
8
 
@@ -27,6 +27,7 @@ AddressKit is actively maintained and developed by [Bradley Hodges](https://gith
27
27
  AddressKit is a comprehensive solution for managing and validating Australian addresses. Notable features include:
28
28
 
29
29
  - ✅ **Autocomplete:** Blazingly fast search and autocomplete of Australian addresses based on partial input with result paging, sorting, and filtering
30
+ - ✅ **Locality Search:** Dedicated suburb/postcode autocomplete for when you only need locality lookups without full address results
30
31
  - ✅ **Canonical validation**: Validation is built into AddressKit's core data model since every address is resolved from the [G-NAF](https://data.gov.au/data/dataset/geocoded-national-address-file-g-naf) by default, so "valid" automatically means "authoritatively correct"
31
32
  - ✅ **Always up-to-date:** AddressKit automatically refreshes its data from the [G-NAF](https://data.gov.au/data/dataset/geocoded-national-address-file-g-naf) every 3 months
32
33
  - ✅ **Real-time address validation:** Address validation and autocomplete for Australian addresses
@@ -38,53 +39,284 @@ AddressKit is a comprehensive solution for managing and validating Australian ad
38
39
  - ✅ **Geocoding:** Geocoding of addresses to latitude and longitude coordinates
39
40
  - ✅ **Cross-platform:** Works on Windows, macOS, and Linux
40
41
 
42
+ ---
41
43
  # Table of Contents
42
44
 
43
- - [About](#about)
44
- - [Table of Contents](#table-of-contents)
45
45
  - [Installation](#installation)
46
+ - [Docker Compose](#docker-compose)
47
+ - [Using npm](#using-npm)
48
+ - [Enabling Geocoding](#enabling-geocoding)
49
+ - [Updating AddressKit](#updating-addresskit)
46
50
  - [CLI Reference](#cli-reference)
47
51
  - [Commands](#commands)
48
- - [Load Command](#load-command)
49
- - [Start Command](#start-command)
50
- - [Version Command](#version-command)
51
- - [Quick Start](#quick-start)
52
- - [Self Hosted](#self-hosted)
52
+ - [`load` Command](#load-command)
53
+ - [`start` Command](#start-command)
54
+ - [`version` Command](#version-command)
55
+ - [Environment Variables](#environment-variables)
53
56
  - [API Endpoints](#api-endpoints)
54
57
  - [Search / Autocomplete](#search--autocomplete)
55
58
  - [Get Address Details](#get-address-details)
59
+ - [Search Localities](#search-localities)
60
+ - [Get Locality Details](#get-locality-details)
56
61
  - [Error Responses](#error-responses)
57
- - [Configuration](#configuration)
58
62
  - [System Requirements](#system-requirements)
63
+ - [Supported Platforms](#supported-platforms)
59
64
 
65
+ ---
60
66
  # Installation
61
67
 
62
- Install AddressKit globally using npm:
68
+ If you prefer to self-host AddressKit, you have two options for installation: using **[Docker Compose](#docker-compose) (recommended)**, or globally using [npm](#using-npm).
69
+
70
+ ## Docker Compose
71
+
72
+ The fastest way to get AddressKit running. No installation required - just good ol' Docker.
73
+
74
+ #### 1. Create `docker-compose.yml` in your project root, and copy this into it:
75
+
76
+ ```yaml
77
+ services:
78
+ opensearch:
79
+ image: opensearchproject/opensearch:1.3.20
80
+ environment:
81
+ - discovery.type=single-node
82
+ - plugins.security.disabled=true
83
+ - OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g
84
+ ports:
85
+ - "9200:9200"
86
+ volumes:
87
+ - opensearch-data:/usr/share/opensearch/data
88
+ healthcheck:
89
+ test: ["CMD-SHELL", "curl -fsS http://localhost:9200/_cluster/health >/dev/null || exit 1"]
90
+ interval: 10s
91
+ timeout: 10s
92
+ retries: 30
93
+ start_period: 60s
94
+ restart: unless-stopped
95
+
96
+ api:
97
+ image: bradleyhodges/addresskit:latest
98
+ environment:
99
+ - ELASTIC_HOST=opensearch
100
+ - ELASTIC_PORT=9200
101
+ - PORT=8080
102
+ ports:
103
+ - "8080:8080"
104
+ depends_on:
105
+ opensearch:
106
+ condition: service_healthy
107
+ command: ["addresskit", "start", "--daemon"]
108
+ restart: unless-stopped
109
+ healthcheck:
110
+ test: ["CMD-SHELL", "curl -fsS http://localhost:8080/addresses?q=test >/dev/null || exit 1"]
111
+ interval: 30s
112
+ timeout: 10s
113
+ retries: 3
114
+ start_period: 30s
115
+
116
+ loader:
117
+ image: bradleyhodges/addresskit:latest
118
+ profiles:
119
+ - loader
120
+ environment:
121
+ - ELASTIC_HOST=opensearch
122
+ - ELASTIC_PORT=9200
123
+ - COVERED_STATES=${COVERED_STATES:-ACT}
124
+ # - ADDRESSKIT_ENABLE_GEO=true # Uncomment to enable geocoding
125
+ volumes:
126
+ - gnaf-data:/home/node/gnaf
127
+ depends_on:
128
+ opensearch:
129
+ condition: service_healthy
130
+ command: ["addresskit", "load"]
131
+ restart: "no"
132
+
133
+ # Optional: OpenSearch Dashboards for monitoring
134
+ dashboards:
135
+ image: opensearchproject/opensearch-dashboards:1.3.20
136
+ profiles:
137
+ - monitoring
138
+ environment:
139
+ - OPENSEARCH_HOSTS=["http://opensearch:9200"]
140
+ - DISABLE_SECURITY_DASHBOARDS_PLUGIN=true
141
+ ports:
142
+ - "5601:5601"
143
+ depends_on:
144
+ opensearch:
145
+ condition: service_healthy
146
+ restart: unless-stopped
147
+
148
+ volumes:
149
+ opensearch-data:
150
+ gnaf-data:
151
+ ```
152
+
153
+ #### 2. Start OpenSearch and the AddressKit REST API server:
63
154
 
64
155
  ```bash
65
- npm install -g @bradleyhodges/addresskit
156
+ docker compose up -d
66
157
  ```
67
158
 
68
- Or using yarn:
159
+ #### 3. Load the G-NAF address data into the search index (first time only):
69
160
 
70
161
  ```bash
71
- yarn global add @bradleyhodges/addresskit
162
+ docker compose --profile loader run --rm loader
72
163
  ```
73
164
 
74
- Or using pnpm:
165
+ > [!TIP]
166
+ > By default, only ACT is loaded for quick testing. To load specific states, set the `COVERED_STATES` environment variable:
167
+ > ```bash
168
+ > COVERED_STATES=NSW,VIC,QLD docker compose --profile loader run --rm loader
169
+ > ```
170
+ > Or to load all states (takes longer, requires more disk space):
171
+ > ```bash
172
+ > COVERED_STATES= docker compose --profile loader run --rm loader
173
+ > ```
174
+
175
+ #### 4. Test the API by searching for addresses:
75
176
 
76
177
  ```bash
77
- pnpm add -g @bradleyhodges/addresskit
178
+ # Search for addresses (autocomplete)
179
+ curl -H "Accept: application/vnd.api+json" \
180
+ "http://localhost:8080/addresses?q=LEVEL+25,+TOWER+3"
181
+
182
+ # Get detailed information for a specific address
183
+ curl -H "Accept: application/vnd.api+json" \
184
+ "http://localhost:8080/addresses/GAVIC411711441"
78
185
  ```
79
186
 
80
- After installation, the `addresskit` command will be available globally in your terminal.
187
+ The API returns JSON:API compliant responses. See [API Endpoints](#api-endpoints) for detailed examples.
81
188
 
82
- **Verify Installation:**
189
+ #### 5. Optional: Enable monitoring dashboard
190
+
191
+ ```bash
192
+ docker compose --profile monitoring up -d
193
+ ```
194
+
195
+ Access the OpenSearch Dashboards at http://localhost:5601 to monitor your index and search performance.
196
+
197
+ ### Docker Compose Services
198
+
199
+ | Service | Description | Default Port | Profile |
200
+ |---------|-------------|--------------|---------|
201
+ | `opensearch` | Search backend | 9200 | default |
202
+ | `api` | REST API server | 8080 | default |
203
+ | `loader` | G-NAF data loader | - | `loader` |
204
+ | `dashboards` | OpenSearch Dashboards | 5601 | `monitoring` |
205
+
206
+ ### Configuration
207
+
208
+ For production deployments or advanced configuration, create a `.env` file alongside your `docker-compose.yml`:
209
+
210
+ ```env
211
+ # States to load (comma-separated: ACT,NSW,VIC,QLD,SA,WA,TAS,NT)
212
+ COVERED_STATES=NSW,VIC
213
+
214
+ # Enable geocoding (latitude/longitude)
215
+ ADDRESSKIT_ENABLE_GEO=true
216
+
217
+ # OpenSearch memory (adjust based on available RAM)
218
+ OPENSEARCH_HEAP=2g
219
+
220
+ # API server port
221
+ API_PORT=8080
222
+
223
+ # CORS origin (set to your domain in production)
224
+ CORS_ORIGIN=https://example.com
225
+ ```
226
+
227
+ See [Environment Variables](#environment-variables) for all available options.
228
+
229
+ ## Using npm
230
+
231
+ #### 1. Ensure you have Node.js >= 24.0.0 installed. You can check your Node.js version by running:
232
+
233
+ ```bash
234
+ node --version
235
+ ```
236
+
237
+ #### 2. Install the latest version of the AddressKit package globally using npm:
238
+
239
+ ```bash
240
+ npm install -g @bradleyhodges/addresskit
241
+ ```
242
+
243
+ After installation, the `addresskit` command will be available globally in your terminal. Verify the installation by running:
83
244
 
84
245
  ```bash
85
246
  addresskit --version
86
247
  ```
87
248
 
249
+ #### 3. AddressKit requires OpenSearch as its search and indexing backend. If you don't already have an OpenSearch instance running, start one with Docker:
250
+
251
+ ```bash
252
+ docker run -d --name opensearch \
253
+ -p 9200:9200 -p 9300:9300 \
254
+ -e "discovery.type=single-node" \
255
+ -e "plugins.security.disabled=true" \
256
+ -e "OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g" \
257
+ opensearchproject/opensearch:1.3.20
258
+ ```
259
+
260
+ #### 4. Configure AddressKit by creating a `.env` file in the root of your project and adding the following variables ([see below](#environment-variables) for all supported environment variables):
261
+
262
+ ```env
263
+ ELASTIC_HOST=opensearch
264
+ ELASTIC_PORT=9200
265
+ ELASTIC_PROTOCOL=http
266
+ ADDRESSKIT_ENABLE_GEO=0 # disable geocoding support (requires more memory) by default
267
+ ```
268
+
269
+ #### 5. Start the AddressKit API server by running:
270
+
271
+ ```bash
272
+ addresskit start
273
+ ```
274
+
275
+ #### 6. Load the G-NAF address data into the search index by running:
276
+
277
+ ```bash
278
+ addresskit load
279
+ ```
280
+
281
+ > [!NOTE]
282
+ > If you are using AddressKit for the first time, you will need to load the G-NAF address data into the search index. This will take a while, depending on the size of the G-NAF dataset. Read more about the load command [here](#load-command).
283
+
284
+ ---
285
+ # Enabling Geocoding
286
+
287
+ Geocoding is an optional feature that can be enabled by setting the `ADDRESSKIT_ENABLE_GEO` environment variable to `1`. This will enable geocoding of addresses to latitude and longitude coordinates. Note that geocoding requires more memory, and is disabled by default. To enable geocoding, add the following to your `.env` or `docker-compose.yml` file:
288
+
289
+ ```env
290
+ ADDRESSKIT_ENABLE_GEO=1
291
+ NODE_OPTIONS=--max_old_space_size=8196 # This is the maximum memory allocation for the Node.js process. Adjust this value based on your system's available memory.
292
+ ```
293
+
294
+ > [!IMPORTANT] Geocoding requires more memory
295
+ > With geocoding enabled, indexing takes longer and requires more memory (8GB recommended). If you are experiencing memory issues, you can adjust the `NODE_OPTIONS` value to allocate more memory to the Node.js process. You can read more about the `NODE_OPTIONS` environment variable [here](https://nodejs.org/api/cli.html#node_optionsoptions).
296
+
297
+ ---
298
+ # Updating AddressKit
299
+
300
+ AddressKit is updated regularly to fix bugs and add new features. You can update AddressKit by pulling the latest Docker image:
301
+
302
+ ```bash
303
+ docker pull bradleyhodges/addresskit:latest
304
+ ```
305
+
306
+ Or, if you are using npm, by running:
307
+
308
+ ```bash
309
+ npm install -g @bradleyhodges/addresskit
310
+ ```
311
+
312
+ In addition to keeping AddressKit updated, you should regularly update the G-NAF address data to ensure you have the latest addresses. Updates to the G-NAF data are released every 3 months. To automate this chore, you could set up a cron job to keep AddressKit updated. For example, in Linux/macOS, you could add the following to your `crontab`:
313
+
314
+ ```bash
315
+ # Run on the 1st of every month at 3am
316
+ 0 3 1 * * addresskit load --clear # Note: passing the --clear flag will clear the index before loading the latest data, which may cause some downtime. Use with caution.
317
+ ```
318
+
319
+ ---
88
320
  # CLI Reference
89
321
 
90
322
  AddressKit provides a beautiful, intuitive command-line interface for managing your address validation service.
@@ -122,7 +354,7 @@ Commands:
122
354
  | `addresskit version` | Display version and environment information |
123
355
  | `addresskit help` | Display help information |
124
356
 
125
- ## Load Command
357
+ ## `load` Command
126
358
 
127
359
  Downloads the latest G-NAF dataset from data.gov.au, extracts it, and indexes all addresses into your OpenSearch instance.
128
360
 
@@ -173,7 +405,7 @@ addresskit load -d
173
405
  | `VIC` | Victoria |
174
406
  | `WA` | Western Australia |
175
407
 
176
- ## Start Command
408
+ ## `start` Command
177
409
 
178
410
  Starts the REST API server for address search and validation.
179
411
 
@@ -205,7 +437,7 @@ addresskit start -d
205
437
  addresskit start -d -p 9000
206
438
  ```
207
439
 
208
- ## Version Command
440
+ ## `version` Command
209
441
 
210
442
  Displays detailed version and environment information.
211
443
 
@@ -213,115 +445,73 @@ Displays detailed version and environment information.
213
445
  addresskit version
214
446
  ```
215
447
 
216
- # Quick Start
217
-
218
- ## Self Hosted
219
-
220
- ### 1. Install AddressKit
221
-
222
- ```bash
223
- npm install -g @bradleyhodges/addresskit
224
- ```
225
-
226
- ### 2. Start OpenSearch
227
-
228
- ```bash
229
- docker pull opensearchproject/opensearch:1.3.20
230
- docker run -p 9200:9200 -p 9300:9300 \
231
- -e "discovery.type=single-node" \
232
- -e "plugins.security.disabled=true" \
233
- opensearchproject/opensearch:1.3.20
234
- ```
235
-
236
- ### 3. Configure Environment Variables
237
-
238
- **Linux/macOS:**
239
- ```bash
240
- export ELASTIC_PORT=9200
241
- export ELASTIC_HOST=localhost
242
- ```
243
-
244
- **Windows (PowerShell):**
245
- ```powershell
246
- $env:ELASTIC_PORT = "9200"
247
- $env:ELASTIC_HOST = "localhost"
248
- ```
249
-
250
- **Windows (Command Prompt):**
251
- ```cmd
252
- set ELASTIC_PORT=9200
253
- set ELASTIC_HOST=localhost
254
- ```
255
-
256
- ### 4. Load Address Data
257
-
258
- In a new terminal window:
259
-
260
- ```bash
261
- # Load all states (takes approximately 1 hour for 13+ million addresses)
262
- addresskit load
263
-
264
- # Or load specific states for faster initial setup
265
- addresskit load --states VIC,NSW
266
- ```
267
-
268
- **Optional: Enable Geocoding**
269
-
270
- ```bash
271
- # Linux/macOS
272
- export ADDRESSKIT_ENABLE_GEO=1
273
- export NODE_OPTIONS=--max_old_space_size=8196
274
- addresskit load --geo
275
-
276
- # Windows (PowerShell)
277
- $env:ADDRESSKIT_ENABLE_GEO = "1"
278
- $env:NODE_OPTIONS = "--max_old_space_size=8196"
279
- addresskit load --geo
280
- ```
448
+ ---
449
+ # Environment Variables
281
450
 
282
- > **Note:** With geocoding enabled, indexing takes longer and requires more memory (8GB recommended).
451
+ ### Core Settings
283
452
 
284
- ### 5. Start the API Server
285
-
286
- In another terminal window:
453
+ | Environment Variable | Description | Default |
454
+ |---------------------|-------------|---------|
455
+ | `ELASTIC_HOST` | OpenSearch host | `localhost` |
456
+ | `ELASTIC_PORT` | OpenSearch port | `9200` |
457
+ | `ELASTIC_PROTOCOL` | Protocol (`http` or `https`) | `http` |
458
+ | `ELASTIC_USERNAME` | OpenSearch username (optional) | |
459
+ | `ELASTIC_PASSWORD` | OpenSearch password (optional) | |
460
+ | `PORT` | API server port | `8080` |
461
+ | `ES_INDEX_NAME` | OpenSearch index name for addresses | `addresskit` |
462
+ | `ES_LOCALITY_INDEX_NAME` | OpenSearch index name for localities | `addresskit-localities` |
463
+ | `NODE_ENV` | Environment (`production` or `development`) | `production` |
287
464
 
288
- ```bash
289
- addresskit start
290
- ```
465
+ ### Data Loading
291
466
 
292
- Or specify a custom port:
467
+ | Environment Variable | Description | Default |
468
+ |---------------------|-------------|---------|
469
+ | `COVERED_STATES` | Comma-separated list of states to load (ACT,NSW,VIC,QLD,SA,WA,TAS,NT) | All states |
470
+ | `ADDRESSKIT_ENABLE_GEO` | Enable geocoding (`true` or `1` to enable) | Disabled |
471
+ | `ES_CLEAR_INDEX` | Clear index before loading | `false` |
472
+ | `GNAF_DIR` | Directory for G-NAF data cache | `/home/node/gnaf` |
293
473
 
294
- ```bash
295
- addresskit start --port 3000
296
- ```
474
+ ### Performance & Caching
297
475
 
298
- ### 6. Test the API
476
+ | Environment Variable | Description | Default |
477
+ |---------------------|-------------|---------|
478
+ | `PAGE_SIZE` | Default results per page | `8` |
479
+ | `ADDRESSKIT_CACHE_ENABLED` | Enable response caching | `true` |
480
+ | `ADDRESSKIT_CACHE_MAX_ENTRIES` | Maximum cached entries | `1000` |
481
+ | `ADDRESSKIT_CACHE_TTL_MS` | Cache TTL in milliseconds | `300000` (5 min) |
482
+ | `ADDRESSKIT_DYNAMIC_RESOURCES` | Enable dynamic resource management | `true` |
483
+ | `ADDRESSKIT_TARGET_MEMORY_UTILIZATION` | Target memory usage ratio | `0.7` |
299
484
 
300
- ```bash
301
- # Search for addresses (autocomplete)
302
- curl -H "Accept: application/vnd.api+json" \
303
- "http://localhost:8080/addresses?q=LEVEL+25,+TOWER+3"
485
+ ### CORS Configuration
304
486
 
305
- # Get detailed information for a specific address
306
- curl -H "Accept: application/vnd.api+json" \
307
- "http://localhost:8080/addresses/GAVIC411711441"
308
- ```
487
+ | Environment Variable | Description | Default |
488
+ |---------------------|-------------|---------|
489
+ | `ADDRESSKIT_ACCESS_CONTROL_ALLOW_ORIGIN` | CORS allowed origin | `*` |
490
+ | `ADDRESSKIT_ACCESS_CONTROL_EXPOSE_HEADERS` | CORS exposed headers | |
491
+ | `ADDRESSKIT_ACCESS_CONTROL_ALLOW_HEADERS` | CORS allowed headers | |
309
492
 
310
- The API returns JSON:API compliant responses. See [API Endpoints](#api-endpoints) for detailed examples.
493
+ ### Retry & Timeout Settings
311
494
 
312
- ### 7. Keep Data Updated
495
+ | Environment Variable | Description | Default |
496
+ |---------------------|-------------|---------|
497
+ | `ADDRESSKIT_INDEX_TIMEOUT` | Index operation timeout | `300s` |
498
+ | `ADDRESSKIT_INDEX_BACKOFF` | Initial backoff delay (ms) | `30000` |
499
+ | `ADDRESSKIT_INDEX_BACKOFF_INCREMENT` | Backoff increment (ms) | `30000` |
500
+ | `ADDRESSKIT_INDEX_BACKOFF_MAX` | Maximum backoff delay (ms) | `600000` |
501
+ | `ADDRESSKIT_INDEX_MAX_RETRIES` | Maximum retry attempts | `10` |
313
502
 
314
- An updated G-NAF is released every 3 months. Set up a cron job to keep AddressKit updated:
503
+ ### Container Startup (Docker only)
315
504
 
316
- **Linux/macOS (crontab):**
317
- ```bash
318
- # Run on the 1st of every month at 3am
319
- 0 3 1 * * addresskit load --clear
320
- ```
505
+ | Environment Variable | Description | Default |
506
+ |---------------------|-------------|---------|
507
+ | `ADDRESSKIT_STARTUP_MAX_RETRIES` | Max retries waiting for OpenSearch | `60` |
508
+ | `ADDRESSKIT_STARTUP_RETRY_INTERVAL` | Seconds between retries | `5` |
509
+ | `ADDRESSKIT_SKIP_OPENSEARCH_WAIT` | Skip waiting for OpenSearch | `false` |
510
+ | `ADDRESSKIT_QUIET` | Suppress startup banner | `false` |
321
511
 
322
- **Windows (Task Scheduler):**
323
- Create a scheduled task to run `addresskit load --clear` monthly.
512
+ > **Note:** When adjusting `PAGE_SIZE`, consider how quickly you want initial results returned. For most use cases, leave it at 8 and use pagination for additional results. Why 8? [Mechanical Sympathy](https://dzone.com/articles/mechanical-sympathy).
324
513
 
514
+ ---
325
515
  # API Endpoints
326
516
 
327
517
  The AddressKit API conforms to the [JSON:API v1.1 specification](https://jsonapi.org/format/). All responses use the `application/vnd.api+json` media type.
@@ -331,6 +521,9 @@ The AddressKit API conforms to the [JSON:API v1.1 specification](https://jsonapi
331
521
  | `/addresses?q=<query>` | GET | Search for addresses (autocomplete) |
332
522
  | `/addresses?q=<query>&page[number]=<n>` | GET | Search with pagination |
333
523
  | `/addresses/:id` | GET | Get detailed information for a specific address |
524
+ | `/localities?q=<query>` | GET | Search for localities/suburbs (autocomplete) |
525
+ | `/localities?q=<query>&page[number]=<n>` | GET | Search localities with pagination |
526
+ | `/localities/:id` | GET | Get detailed information for a specific locality |
334
527
  | `/docs` | GET | OpenAPI/Swagger documentation |
335
528
 
336
529
  ## Search / Autocomplete
@@ -478,6 +671,110 @@ curl -H "Accept: application/vnd.api+json" \
478
671
  }
479
672
  ```
480
673
 
674
+ ## Search Localities
675
+
676
+ Search for localities (suburbs/postcodes) matching a query string. Returns lightweight autocomplete suggestions - useful when you only need suburb/postcode lookups without full address autocomplete.
677
+
678
+ **Request:**
679
+
680
+ ```bash
681
+ curl -H "Accept: application/vnd.api+json" \
682
+ "http://localhost:8080/localities?q=sydney"
683
+ ```
684
+
685
+ **Response:**
686
+
687
+ ```json
688
+ {
689
+ "jsonapi": {
690
+ "version": "1.1"
691
+ },
692
+ "data": [
693
+ {
694
+ "type": "locality-suggestion",
695
+ "id": "NSW1234",
696
+ "attributes": {
697
+ "display": "SYDNEY NSW 2000",
698
+ "rank": 1
699
+ },
700
+ "links": {
701
+ "self": "/localities/NSW1234"
702
+ }
703
+ },
704
+ {
705
+ "type": "locality-suggestion",
706
+ "id": "NSW5678",
707
+ "attributes": {
708
+ "display": "SYDNEY SOUTH NSW 2000",
709
+ "rank": 0.85
710
+ },
711
+ "links": {
712
+ "self": "/localities/NSW5678"
713
+ }
714
+ }
715
+ ],
716
+ "links": {
717
+ "self": "/localities?q=sydney",
718
+ "first": "/localities?q=sydney",
719
+ "prev": null,
720
+ "next": "/localities?q=sydney&page[number]=2",
721
+ "last": "/localities?q=sydney&page[number]=5"
722
+ },
723
+ "meta": {
724
+ "total": 42,
725
+ "page": 1,
726
+ "pageSize": 10,
727
+ "totalPages": 5
728
+ }
729
+ }
730
+ ```
731
+
732
+ ## Get Locality Details
733
+
734
+ Retrieve comprehensive details for a specific locality by its G-NAF Locality Persistent Identifier (PID). Use this endpoint after a user selects a locality from the autocomplete results.
735
+
736
+ **Request:**
737
+
738
+ ```bash
739
+ curl -H "Accept: application/vnd.api+json" \
740
+ "http://localhost:8080/localities/NSW1234"
741
+ ```
742
+
743
+ **Response:**
744
+
745
+ ```json
746
+ {
747
+ "jsonapi": {
748
+ "version": "1.1"
749
+ },
750
+ "data": {
751
+ "type": "locality",
752
+ "id": "NSW1234",
753
+ "attributes": {
754
+ "localityPid": "NSW1234",
755
+ "name": "SYDNEY",
756
+ "display": "SYDNEY NSW 2000",
757
+ "class": {
758
+ "code": "G",
759
+ "name": "GAZETTED LOCALITY"
760
+ },
761
+ "state": {
762
+ "name": "New South Wales",
763
+ "abbreviation": "NSW"
764
+ },
765
+ "postcode": "2000",
766
+ "postcodes": ["2000", "2001"]
767
+ },
768
+ "links": {
769
+ "self": "/localities/NSW1234"
770
+ }
771
+ },
772
+ "links": {
773
+ "self": "/localities/NSW1234"
774
+ }
775
+ }
776
+ ```
777
+
481
778
  ## Error Responses
482
779
 
483
780
  All error responses follow the JSON:API error format:
@@ -506,55 +803,32 @@ All error responses follow the JSON:API error format:
506
803
  | `503` | Service Unavailable - OpenSearch unavailable |
507
804
  | `504` | Gateway Timeout - Query timeout |
508
805
 
509
- # Configuration
510
-
511
- | Environment Variable | Description | Default |
512
- |---------------------|-------------|---------|
513
- | `ELASTIC_HOST` | OpenSearch host | `localhost` |
514
- | `ELASTIC_PORT` | OpenSearch port | `9200` |
515
- | `ELASTIC_PROTOCOL` | Protocol (`http` or `https`) | `http` |
516
- | `ELASTIC_USERNAME` | OpenSearch username (optional) | |
517
- | `ELASTIC_PASSWORD` | OpenSearch password (optional) | |
518
- | `PORT` | API server port | `8080` |
519
- | `ES_INDEX_NAME` | OpenSearch index name | `addresskit` |
520
- | `COVERED_STATES` | Comma-separated list of states to load | All states |
521
- | `ADDRESSKIT_ENABLE_GEO` | Enable geocoding (`1` to enable) | Disabled |
522
- | `PAGE_SIZE` | Default results per page | `8` |
523
- | `ADDRESSKIT_ACCESS_CONTROL_ALLOW_ORIGIN` | CORS allowed origin | |
524
- | `ADDRESSKIT_ACCESS_CONTROL_EXPOSE_HEADERS` | CORS exposed headers | |
525
- | `ADDRESSKIT_ACCESS_CONTROL_ALLOW_HEADERS` | CORS allowed headers | |
526
- | `ADDRESSKIT_INDEX_TIMEOUT` | Index operation timeout | `30s` |
527
- | `ADDRESSKIT_INDEX_BACKOFF` | Initial backoff delay (ms) | `1000` |
528
- | `ADDRESSKIT_INDEX_BACKOFF_INCREMENT` | Backoff increment (ms) | `1000` |
529
- | `ADDRESSKIT_INDEX_BACKOFF_MAX` | Maximum backoff delay (ms) | `10000` |
530
-
531
- > **Note:** When adjusting `PAGE_SIZE`, consider how quickly you want initial results returned. For most use cases, leave it at 8 and use pagination for additional results. Why 8? [Mechanical Sympathy](https://dzone.com/articles/mechanical-sympathy).
532
-
806
+ ---
533
807
  # System Requirements
534
808
 
535
- ## OpenSearch
809
+ AddressKit is designed to be lightweight and efficient. It is built to run on modest hardware, and is designed to be self-hosted on your own infrastructure.
810
+
811
+ ## Resource Requirements
536
812
 
537
- - OpenSearch >= 1.2.4
538
- - Memory: 1.4 GiB minimum
539
- - CPU: 1 core
813
+ | Deployment Size | States | Memory | Disk | Use Case |
814
+ |-----------------|--------|--------|------|----------|
815
+ | **Small** | 1-2 states (e.g., ACT) | 2GB | 10GB | Development, testing |
816
+ | **Medium** | 3-4 states | 4GB | 30GB | Regional applications |
817
+ | **Large** | All states | 8GB+ | 100GB+ | National production |
540
818
 
541
- ## AddressKit Loader
819
+ These requirements include both AddressKit and OpenSearch. Memory should be split roughly 50/50 between the API server and OpenSearch (adjust `OPENSEARCH_HEAP` accordingly).
542
820
 
543
- ### Default (without geocoding)
544
- - Node.js >= 20.0.0
545
- - Memory: 1 GiB
546
- - CPU: 1 core
821
+ > [!NOTE]
822
+ > If you enable geocoding (`ADDRESSKIT_ENABLE_GEO=true`), increase memory requirements by approximately 50%. For all states with geocoding, we recommend 12GB+ RAM.
547
823
 
548
- ### With Geocoding Enabled
549
- - Node.js >= 20.0.0
550
- - Memory: 8 GiB
551
- - CPU: 4 cores
824
+ ## Production Deployment Tips
552
825
 
553
- ## AddressKit Server
826
+ For production deployments, consider:
554
827
 
555
- - Node.js >= 20.0.0
556
- - Memory: 64 MiB (128 MiB+ recommended)
557
- - CPU: 1 core
828
+ 1. **Security:** Set `CORS_ORIGIN` to your specific domain(s), enable OpenSearch security, use HTTPS via a reverse proxy
829
+ 2. **Performance:** Tune `OPENSEARCH_HEAP` to 50% of available container memory (max 32GB)
830
+ 3. **Reliability:** Set up volume backups for `opensearch-data` and `gnaf-data`, configure log aggregation
831
+ 4. **Monitoring:** Enable the `monitoring` profile to access OpenSearch Dashboards
558
832
 
559
833
  ## Supported Platforms
560
834