Postcodes for Laravel is Joshua Dovey's client for the GB Postcodes API. It returns typed objects for postcode lookups, geography, and proximity searches, with a Laravel validation rule and a fake for tests. If you have used the earlier Laravel wrapper for Postcodes.io, this package connects to a different postcode service and includes boundary and population data.
Look up postcodes and geography
The facade returns a Postcode object rather than an array. This example uses M16 0RA, the postcode for Manchester United's Old Trafford stadium. get() returns null for a postcode that does not resolve; getOrFail() throws a NotFoundException.
use JoshDovey\Postcodes\Facades\Postcodes; $postcode = Postcodes::get('M16 0RA'); $postcode?->latitude();$postcode?->longitude();$postcode?->geography->localAuthorityName;$postcode?->geography->wardName;
The geography object includes administrative areas such as parliamentary constituencies, NHS integrated care boards, and police force areas. The package also exposes census and estimated population figures. For forms, autocomplete() returns a Laravel collection of matches for a partial postcode, while search() resolves multiple postcodes in batches of up to 100 per API request.
Validate a postcode against the dataset
Laravel's validation rules can use ValidPostcode to check whether a postcode exists, rather than only checking its format. unit() requires a full postcode such as M16 0RA.
use JoshDovey\Postcodes\Rules\ValidPostcode; $request->validate([ 'postcode' => ['required', ValidPostcode::unit()],]);
Values with an invalid shape fail locally, without an API request. By default, a format-valid value passes if the API check throws an error. To reject it instead, call (new ValidPostcode)->strict() or set postcodes.validation.strict to true in the published configuration.
Search by distance or boundary
For a delivery area or catchment, radius() finds postcodes near a given postcode. within() accepts a GeoJSON polygon, multipolygon, or feature. You can also calculate the distance between two postcodes, request a distance matrix, or reverse geocode coordinates.
$nearby = Postcodes::radius('M16 0RA', radius: 2, limit: 100); foreach ($nearby as $result) { echo $result->postcode.' '.$result->distance;}
Distance defaults to kilometres, with miles available per call or for the client. Lookups return boundary geometry by default; withoutBoundaries() or a fields selection trims the response when you only need coordinates or names.
Install and test
The package requires PHP 8.2 or later and Laravel 12 or 13. Install it with Composer, then set the API key for the GB Postcodes API:
composer require joshdovey/postcodes
POSTCODES_API_KEY=your-key
Successful API responses are cached for one day by default. The client retries timeouts, connection failures, burst rate limits, and server errors twice by default. It does not retry an exhausted plan quota.
For tests, Postcodes::fake() replaces the client with stubbed responses and records requests:
use JoshDovey\Postcodes\Testing\Fixtures; $fake = Postcodes::fake([ 'v1/postcodes/validate*' => Fixtures::validation('M16 0RA'),]); $result = Postcodes::validate('M16 0RA'); $fake->assertSent('v1/postcodes/validate*');
The Postcodes for Laravel repository has the full API reference, configuration options, and examples for boundaries and testing.