Java libraries for Nigeria's National Digital Alphanumeric Postcode System (NDAPS), the building-level postcode NIPOST launched in October 2026. Parse, validate and format postcodes offline, and call the postcode.gov.ng API for lookup, autocomplete and reverse geocoding.
Part of the ng-postcode project, which has the same behaviour in Rust, Python and JavaScript. All four run the same shared test cases.
| Artifact | What it does | Dependencies |
|---|---|---|
io.github.adeniyikayodee:ng-postcode |
Parse, validate and format codes offline | None |
io.github.adeniyikayodee:ng-postcode-api |
Requests, decoding and an HTTP client | The core and Jackson |
<dependency>
<groupId>io.github.adeniyikayodee</groupId>
<artifactId>ng-postcode-api</artifactId>
<version>0.2.0</version>
</dependency>Needs Java 17 or later. Neither library has been tested on Android, and the client cannot run there, as Android has no java.net.http.
Expected failures are returned as values of a sealed type, so the compiler makes you handle them.
import io.github.adeniyikayodee.ngpostcode.Postcode;
import io.github.adeniyikayodee.ngpostcode.Segment;
if (Postcode.parse("ek 01 a03 fk 01") instanceof Postcode code) {
System.out.println(code); // EK-01-A03-FK-01
System.out.println(code.compact()); // EK01A03FK01, store this
System.out.println(code.spaced()); // EK 01 A03 FK 01
System.out.println(code.prefix(Segment.AREA)); // EK-01-A03-FK
}Postcode.parseaccepts hyphenated, spaced or compact input in either case, and returns aPostcodeor aParseErrorsuch as "invalid lga segment".Postcode.parseLenientfirst swaps look-alikes that cannot occur where they stand (O/0,I/1,S/5,B/8) and reports how many it changed.Postcode.fromSegmentsassembles a code from its parts and zero-fills the LGA and unit.Postcode.isValidanswers yes or no.
A well-formed code is not necessarily assigned to a building. Only the API can confirm that a postcode exists.
import io.github.adeniyikayodee.ngpostcode.Postcode;
import io.github.adeniyikayodee.ngpostcode.api.Api;
import io.github.adeniyikayodee.ngpostcode.api.Client;
import io.github.adeniyikayodee.ngpostcode.api.Lookup;
import io.github.adeniyikayodee.ngpostcode.api.Result;
var client = new Client(System.getenv("NG_POSTCODE_API_KEY"));
Result<Lookup> found = client.send(Api.lookup(new Postcode("FC03B06AG12"), 1));
if (found instanceof Result.Ok<Lookup> ok) {
System.out.println(ok.value().valid() + " " + ok.value().status()); // true valid
} else if (found instanceof Result.Failed<Lookup> failed) {
System.err.println(failed.failure()); // e.g. "invalid_api_key (401): ..."
}Api covers lookup, autocomplete, reverse and nearby. Each returns a plain Request, and Api.decode turns a status and body into a typed result, so it works with any HTTP client. A request that cannot succeed, such as a level outside 1 to 5, a blank autocomplete or a coordinate that is not finite, throws IllegalArgumentException before anything is sent.
The client never follows redirects, so the key is never sent to another host, and it gives up after 10 seconds. Fields the API may omit are null.
Get a key from the NIPOST developer dashboard. Level 1 lookups confirm a code is assigned; levels 2 and up return address details and consume credits.
MIT